@lesjoursfr/edith 2.1.2 → 2.1.3
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/build/edith.css +1 -0
- package/build/edith.js +1 -0
- package/dist/core/dom.d.ts +224 -0
- package/dist/core/dom.js +480 -0
- package/dist/core/edit.d.ts +36 -0
- package/dist/core/edit.js +255 -0
- package/dist/core/events.d.ts +47 -0
- package/dist/core/events.js +100 -0
- package/dist/core/history.d.ts +14 -0
- package/dist/core/history.js +24 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.js +7 -0
- package/dist/core/mode.d.ts +4 -0
- package/dist/core/mode.js +5 -0
- package/dist/core/range.d.ts +45 -0
- package/dist/core/range.js +86 -0
- package/dist/core/throttle.d.ts +53 -0
- package/dist/core/throttle.js +139 -0
- package/dist/css/edith.scss +283 -0
- package/dist/edith-options.d.ts +17 -0
- package/dist/edith-options.js +56 -0
- package/dist/edith.d.ts +30 -0
- package/dist/edith.js +76 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ui/button.d.ts +25 -0
- package/dist/ui/button.js +165 -0
- package/dist/ui/editor.d.ts +37 -0
- package/dist/ui/editor.js +322 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/modal.d.ts +32 -0
- package/dist/ui/modal.js +145 -0
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
/**
|
|
3
|
+
* Based on lodash version of throttle : https://github.com/lodash/lodash/blob/master/throttle.js
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Creates a debounced function that delays invoking `func` until after `wait`
|
|
7
|
+
* milliseconds have elapsed since the last time the debounced function was
|
|
8
|
+
* invoked, or until the next browser frame is drawn. Provide `options` to indicate
|
|
9
|
+
* whether `func` should be invoked on the leading and/or trailing edge of the
|
|
10
|
+
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
|
11
|
+
* debounced function. Subsequent calls to the debounced function return the
|
|
12
|
+
* result of the last `func` invocation.
|
|
13
|
+
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
14
|
+
* invoked on the trailing edge of the timeout only if the debounced function
|
|
15
|
+
* is invoked more than once during the `wait` timeout.
|
|
16
|
+
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
17
|
+
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
18
|
+
* @param {Function} func The function to debounce
|
|
19
|
+
* @param {number} wait The number of milliseconds to delay
|
|
20
|
+
* @param {Object} [options={}] The options object
|
|
21
|
+
* @param {boolean} [options.leading=false] Specify invoking on the leading edge of the timeout
|
|
22
|
+
* @param {boolean} [options.trailing=true] Specify invoking on the trailing edge of the timeout
|
|
23
|
+
* @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's invoked
|
|
24
|
+
* @returns {Function} Returns the new debounced function
|
|
25
|
+
*/
|
|
26
|
+
function debounce(func, wait, options = {}) {
|
|
27
|
+
let lastArgs, lastThis, result, timerId, lastCallTime;
|
|
28
|
+
let lastInvokeTime = 0;
|
|
29
|
+
const leading = !!options.leading;
|
|
30
|
+
const maxing = "maxWait" in options;
|
|
31
|
+
const maxWait = maxing ? Math.max(options.maxWait || 0, wait) : undefined;
|
|
32
|
+
const trailing = "trailing" in options ? !!options.trailing : true;
|
|
33
|
+
function invokeFunc(time) {
|
|
34
|
+
const args = lastArgs;
|
|
35
|
+
const thisArg = lastThis;
|
|
36
|
+
lastArgs = lastThis = undefined;
|
|
37
|
+
lastInvokeTime = time;
|
|
38
|
+
result = func.apply(thisArg, args);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function startTimer(pendingFunc, wait) {
|
|
42
|
+
return setTimeout(pendingFunc, wait);
|
|
43
|
+
}
|
|
44
|
+
function leadingEdge(time) {
|
|
45
|
+
// Reset any `maxWait` timer.
|
|
46
|
+
lastInvokeTime = time;
|
|
47
|
+
// Start the timer for the trailing edge.
|
|
48
|
+
timerId = startTimer(timerExpired, wait);
|
|
49
|
+
// Invoke the leading edge.
|
|
50
|
+
return leading ? invokeFunc(time) : result;
|
|
51
|
+
}
|
|
52
|
+
function remainingWait(time) {
|
|
53
|
+
const timeSinceLastCall = time - lastCallTime;
|
|
54
|
+
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
55
|
+
const timeWaiting = wait - timeSinceLastCall;
|
|
56
|
+
return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
|
|
57
|
+
}
|
|
58
|
+
function shouldInvoke(time) {
|
|
59
|
+
const timeSinceLastCall = time - lastCallTime;
|
|
60
|
+
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
61
|
+
// Either this is the first call, activity has stopped and we're at the
|
|
62
|
+
// trailing edge, the system time has gone backwards and we're treating
|
|
63
|
+
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|
64
|
+
return (lastCallTime === undefined ||
|
|
65
|
+
timeSinceLastCall >= wait ||
|
|
66
|
+
timeSinceLastCall < 0 ||
|
|
67
|
+
(maxing && timeSinceLastInvoke >= maxWait));
|
|
68
|
+
}
|
|
69
|
+
function timerExpired() {
|
|
70
|
+
const time = Date.now();
|
|
71
|
+
if (shouldInvoke(time)) {
|
|
72
|
+
return trailingEdge(time);
|
|
73
|
+
}
|
|
74
|
+
// Restart the timer.
|
|
75
|
+
timerId = startTimer(timerExpired, remainingWait(time));
|
|
76
|
+
}
|
|
77
|
+
function trailingEdge(time) {
|
|
78
|
+
timerId = undefined;
|
|
79
|
+
// Only invoke if we have `lastArgs` which means `func` has been
|
|
80
|
+
// debounced at least once.
|
|
81
|
+
if (trailing && lastArgs) {
|
|
82
|
+
return invokeFunc(time);
|
|
83
|
+
}
|
|
84
|
+
lastArgs = lastThis = undefined;
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
function debounced(...args) {
|
|
88
|
+
const time = Date.now();
|
|
89
|
+
const isInvoking = shouldInvoke(time);
|
|
90
|
+
lastArgs = args;
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
92
|
+
lastThis = this;
|
|
93
|
+
lastCallTime = time;
|
|
94
|
+
if (isInvoking) {
|
|
95
|
+
if (timerId === undefined) {
|
|
96
|
+
return leadingEdge(lastCallTime);
|
|
97
|
+
}
|
|
98
|
+
if (maxing) {
|
|
99
|
+
// Handle invocations in a tight loop.
|
|
100
|
+
timerId = startTimer(timerExpired, wait);
|
|
101
|
+
return invokeFunc(lastCallTime);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (timerId === undefined) {
|
|
105
|
+
timerId = startTimer(timerExpired, wait);
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
return debounced;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Creates a throttled function that only invokes `func` at most once per
|
|
113
|
+
* every `wait` milliseconds (or once per browser frame). Provide `options` to indicate
|
|
114
|
+
* whether `func` should be invoked on the leading and/or trailing edge of the
|
|
115
|
+
* `wait` timeout. The `func` is invoked with the last arguments provided to the
|
|
116
|
+
* throttled function. Subsequent calls to the throttled function return the
|
|
117
|
+
* result of the last `func` invocation.
|
|
118
|
+
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
119
|
+
* invoked on the trailing edge of the timeout only if the throttled function
|
|
120
|
+
* is invoked more than once during the `wait` timeout.
|
|
121
|
+
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
122
|
+
* until the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
123
|
+
* @param {Function} func The function to throttle
|
|
124
|
+
* @param {number} wait The number of milliseconds to throttle invocations to
|
|
125
|
+
* @param {Object} [options={}] The options object
|
|
126
|
+
* @param {boolean} [options.leading=true] Specify invoking on the leading edge of the timeout
|
|
127
|
+
* @param {boolean} [options.trailing=true] Specify invoking on the trailing edge of the timeout
|
|
128
|
+
* @returns {Function} Returns the new throttled function
|
|
129
|
+
*/
|
|
130
|
+
function throttle(func, wait, options = {}) {
|
|
131
|
+
const leading = "leading" in options ? !!options.leading : true;
|
|
132
|
+
const trailing = "trailing" in options ? !!options.trailing : true;
|
|
133
|
+
return debounce(func, wait, {
|
|
134
|
+
leading,
|
|
135
|
+
trailing,
|
|
136
|
+
maxWait: wait,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
export { debounce, throttle };
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
@use "sass:color";
|
|
2
|
+
|
|
3
|
+
$color-toolbar: #212529;
|
|
4
|
+
$color-toolbar-border: #212529;
|
|
5
|
+
$color-button: #e9ecef;
|
|
6
|
+
$color-button-border: #ced4da;
|
|
7
|
+
$color-button-text: #212529;
|
|
8
|
+
$color-tooltip: #000;
|
|
9
|
+
$color-tooltip-text: #fff;
|
|
10
|
+
$color-editor: #fff;
|
|
11
|
+
$color-editor-text: #212529;
|
|
12
|
+
$color-modal: #fff;
|
|
13
|
+
$color-modal-border: #ced4da;
|
|
14
|
+
$color-modal-title: #000;
|
|
15
|
+
$color-modal-text: #212529;
|
|
16
|
+
$color-input-border: #bfbfbf;
|
|
17
|
+
$color-checkbox-background: #0d6efd;
|
|
18
|
+
$color-checkbox-border: #bfbfbf;
|
|
19
|
+
$color-modal-cancel-background: #fff;
|
|
20
|
+
$color-modal-cancel-color: #212529;
|
|
21
|
+
$color-modal-cancel-border: #212529;
|
|
22
|
+
$color-modal-submit-background: #0d6efd;
|
|
23
|
+
$color-modal-submit-color: #fff;
|
|
24
|
+
$color-modal-submit-border: #0d6efd;
|
|
25
|
+
|
|
26
|
+
.edith {
|
|
27
|
+
background-color: $color-toolbar;
|
|
28
|
+
border: 1px solid $color-toolbar-border;
|
|
29
|
+
border-radius: 0.25rem;
|
|
30
|
+
padding: 5px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.edith-toolbar {
|
|
34
|
+
background-color: $color-toolbar;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.edith-btn {
|
|
38
|
+
background-color: $color-button;
|
|
39
|
+
border: 1px solid $color-button-border;
|
|
40
|
+
border-radius: 0.25rem;
|
|
41
|
+
color: $color-button-text;
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
display: inline-block;
|
|
44
|
+
font-size: 1rem;
|
|
45
|
+
font-weight: 900;
|
|
46
|
+
line-height: 1.5;
|
|
47
|
+
padding: 0.375rem 0.75rem;
|
|
48
|
+
text-align: center;
|
|
49
|
+
text-decoration: none;
|
|
50
|
+
user-select: none;
|
|
51
|
+
vertical-align: middle;
|
|
52
|
+
|
|
53
|
+
&:disabled {
|
|
54
|
+
color: color.scale($color-button-text, $lightness: 70%);
|
|
55
|
+
cursor: not-allowed;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.edith-btn-group {
|
|
60
|
+
display: inline-flex;
|
|
61
|
+
position: relative;
|
|
62
|
+
vertical-align: middle;
|
|
63
|
+
|
|
64
|
+
&:not(:first-child) {
|
|
65
|
+
margin-left: 10px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
:not(:first-child) {
|
|
69
|
+
margin-left: -1px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.edith-btn:not(:last-child) {
|
|
73
|
+
border-bottom-right-radius: 0;
|
|
74
|
+
border-top-right-radius: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.edith-btn:not(:first-child) {
|
|
78
|
+
border-bottom-left-radius: 0;
|
|
79
|
+
border-top-left-radius: 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.edith-btn-nbsp {
|
|
84
|
+
&::before {
|
|
85
|
+
content: "\0020";
|
|
86
|
+
display: block;
|
|
87
|
+
height: 16px;
|
|
88
|
+
width: 12px;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.edith-tooltip {
|
|
93
|
+
background: $color-tooltip;
|
|
94
|
+
border-radius: 4px;
|
|
95
|
+
color: $color-tooltip-text;
|
|
96
|
+
font-size: 13px;
|
|
97
|
+
font-weight: bold;
|
|
98
|
+
padding: 4px 8px;
|
|
99
|
+
z-index: 10;
|
|
100
|
+
|
|
101
|
+
.arrow,
|
|
102
|
+
.arrow::before {
|
|
103
|
+
background: inherit;
|
|
104
|
+
height: 8px;
|
|
105
|
+
position: absolute;
|
|
106
|
+
width: 8px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.arrow {
|
|
110
|
+
visibility: hidden;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.arrow::before {
|
|
114
|
+
content: "";
|
|
115
|
+
transform: rotate(45deg);
|
|
116
|
+
visibility: visible;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&[data-popper-placement^="top"] > .arrow {
|
|
120
|
+
bottom: -4px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&[data-popper-placement^="bottom"] > .arrow {
|
|
124
|
+
top: -4px;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
&[data-popper-placement^="left"] > .arrow {
|
|
128
|
+
right: -4px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&[data-popper-placement^="right"] > .arrow {
|
|
132
|
+
left: -4px;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.edith-editing-area {
|
|
137
|
+
background-color: $color-editor;
|
|
138
|
+
border-radius: 0.25rem;
|
|
139
|
+
margin-top: 5px;
|
|
140
|
+
padding: 5px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.edith-visual,
|
|
144
|
+
.edith-code {
|
|
145
|
+
height: 100%;
|
|
146
|
+
outline: none;
|
|
147
|
+
overflow: auto;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.edith-hidden {
|
|
151
|
+
display: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.edith-visual {
|
|
155
|
+
color: $color-editor-text;
|
|
156
|
+
|
|
157
|
+
.edith-nbsp {
|
|
158
|
+
color: color.scale($color-button-text, $lightness: 70%);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.edith-modal {
|
|
163
|
+
background: $color-modal;
|
|
164
|
+
border: 2px solid $color-modal-border;
|
|
165
|
+
border-radius: 10px;
|
|
166
|
+
left: calc(50% - 200px);
|
|
167
|
+
position: fixed;
|
|
168
|
+
top: 20%;
|
|
169
|
+
width: 400px;
|
|
170
|
+
z-index: 10;
|
|
171
|
+
|
|
172
|
+
.edith-modal-header {
|
|
173
|
+
border-bottom: 1px solid $color-modal-border;
|
|
174
|
+
color: $color-modal-title;
|
|
175
|
+
font-size: 20px;
|
|
176
|
+
font-weight: 700;
|
|
177
|
+
line-height: 1.4;
|
|
178
|
+
padding: 5px 10px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.edith-modal-content {
|
|
182
|
+
color: $color-modal-text;
|
|
183
|
+
margin: 10px;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.edith-modal-input {
|
|
187
|
+
display: flex;
|
|
188
|
+
flex-wrap: wrap;
|
|
189
|
+
margin: 10px 0;
|
|
190
|
+
|
|
191
|
+
label,
|
|
192
|
+
input {
|
|
193
|
+
width: 100%;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
input {
|
|
197
|
+
appearance: none;
|
|
198
|
+
background-clip: padding-box;
|
|
199
|
+
background-color: $color-modal;
|
|
200
|
+
border: 1px solid $color-checkbox-border;
|
|
201
|
+
border-radius: 0.25rem;
|
|
202
|
+
font-size: 1rem;
|
|
203
|
+
font-weight: 400;
|
|
204
|
+
line-height: 1.5;
|
|
205
|
+
outline: 0;
|
|
206
|
+
padding: 0.375rem 0.75rem;
|
|
207
|
+
width: 100%;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
label {
|
|
211
|
+
font-size: 16px;
|
|
212
|
+
font-weight: 700;
|
|
213
|
+
margin-bottom: 5px;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.edith-modal-checkbox {
|
|
218
|
+
margin: 10px 0;
|
|
219
|
+
|
|
220
|
+
label {
|
|
221
|
+
display: flex;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
input {
|
|
225
|
+
appearance: none;
|
|
226
|
+
background-color: $color-modal;
|
|
227
|
+
background-position: 50%;
|
|
228
|
+
background-repeat: no-repeat;
|
|
229
|
+
background-size: contain;
|
|
230
|
+
border: 1px solid $color-checkbox-border;
|
|
231
|
+
border-radius: 0.25em;
|
|
232
|
+
height: 1em;
|
|
233
|
+
margin-top: 0.25em;
|
|
234
|
+
vertical-align: top;
|
|
235
|
+
width: 1em;
|
|
236
|
+
|
|
237
|
+
&:checked {
|
|
238
|
+
background-color: $color-checkbox-background;
|
|
239
|
+
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3E%3C/svg%3E");
|
|
240
|
+
border-color: $color-checkbox-background;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.edith-modal-footer {
|
|
246
|
+
border-top: 1px solid $color-modal-border;
|
|
247
|
+
display: flex;
|
|
248
|
+
justify-content: flex-end;
|
|
249
|
+
padding: 5px 10px;
|
|
250
|
+
|
|
251
|
+
:not(:last-child) {
|
|
252
|
+
margin-right: 10px;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.edith-modal-cancel,
|
|
257
|
+
.edith-modal-submit {
|
|
258
|
+
border: 1px solid transparent;
|
|
259
|
+
border-radius: 0.25rem;
|
|
260
|
+
cursor: pointer;
|
|
261
|
+
display: inline-block;
|
|
262
|
+
font-size: 1rem;
|
|
263
|
+
font-weight: 400;
|
|
264
|
+
line-height: 1.5;
|
|
265
|
+
padding: 0.375rem 0.75rem;
|
|
266
|
+
text-align: center;
|
|
267
|
+
text-decoration: none;
|
|
268
|
+
user-select: none;
|
|
269
|
+
vertical-align: middle;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.edith-modal-cancel {
|
|
273
|
+
background-color: $color-modal-cancel-background;
|
|
274
|
+
border-color: $color-modal-cancel-border;
|
|
275
|
+
color: $color-modal-cancel-color;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.edith-modal-submit {
|
|
279
|
+
background-color: $color-modal-submit-background;
|
|
280
|
+
border-color: $color-modal-submit-border;
|
|
281
|
+
color: $color-modal-submit-color;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Edith } from "./edith.js";
|
|
2
|
+
import { EdithButton } from "./ui/index.js";
|
|
3
|
+
export type EdithToolbarOption = [string, string[]][];
|
|
4
|
+
export type EdithButtonsOption = {
|
|
5
|
+
[keyof: string]: (context: Edith) => EdithButton;
|
|
6
|
+
};
|
|
7
|
+
export type EdithOptions = {
|
|
8
|
+
height: number;
|
|
9
|
+
resizable: boolean;
|
|
10
|
+
toolbar: EdithToolbarOption;
|
|
11
|
+
buttons: EdithButtonsOption;
|
|
12
|
+
initialContent: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Edith default options
|
|
16
|
+
*/
|
|
17
|
+
export declare const DefaultOptions: EdithOptions;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edith default options
|
|
3
|
+
*/
|
|
4
|
+
export const DefaultOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* The editor's height
|
|
7
|
+
*
|
|
8
|
+
* @type {number}
|
|
9
|
+
* @default 80
|
|
10
|
+
*/
|
|
11
|
+
height: 80,
|
|
12
|
+
/**
|
|
13
|
+
* Control if the editor can be resized by the user
|
|
14
|
+
*
|
|
15
|
+
* @type {boolean}
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
resizable: false,
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* An array that define which button is shown in the toolbar and how they are grouped.
|
|
22
|
+
*
|
|
23
|
+
* @type {EdithToolbarOption}
|
|
24
|
+
* @example
|
|
25
|
+
* toolbar: [
|
|
26
|
+
* ["style", ["bold", "italic", "underline", "strikethrough"]],
|
|
27
|
+
* ["extra", ["subscript", "superscript"]]
|
|
28
|
+
* ]
|
|
29
|
+
*/
|
|
30
|
+
toolbar: [["style", ["bold", "italic", "underline", "strikethrough"]]],
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* Associative object with the button name and builder to create it.
|
|
34
|
+
*
|
|
35
|
+
* @type {EdithButtonsOption}
|
|
36
|
+
* @example
|
|
37
|
+
* buttons: {
|
|
38
|
+
* bold: (context: Edith) =>
|
|
39
|
+
* new EdithButton(context, {
|
|
40
|
+
* icon: "fa-solid fa-bold",
|
|
41
|
+
* title: "Gras",
|
|
42
|
+
* onclick: (ctx: Edith, event: Event) => {
|
|
43
|
+
* ctx.editor.wrapInsideTag("b");
|
|
44
|
+
* },
|
|
45
|
+
* }),
|
|
46
|
+
* }
|
|
47
|
+
*/
|
|
48
|
+
buttons: {},
|
|
49
|
+
/**
|
|
50
|
+
* The editor's initial content
|
|
51
|
+
*
|
|
52
|
+
* @type {string}
|
|
53
|
+
* @default ""
|
|
54
|
+
*/
|
|
55
|
+
initialContent: "",
|
|
56
|
+
};
|
package/dist/edith.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Events } from "./core/index.js";
|
|
2
|
+
import { EdithOptions } from "./edith-options.js";
|
|
3
|
+
import { EdithButton, EdithEditor } from "./ui/index.js";
|
|
4
|
+
declare global {
|
|
5
|
+
interface HTMLElement {
|
|
6
|
+
edith?: Edith;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export { EdithButton };
|
|
10
|
+
export declare class Edith {
|
|
11
|
+
private readonly element;
|
|
12
|
+
readonly toolbar: HTMLDivElement;
|
|
13
|
+
readonly editor: EdithEditor;
|
|
14
|
+
readonly modals: HTMLDivElement;
|
|
15
|
+
/**
|
|
16
|
+
* Create a new editor
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {HTMLElement} element - The <input> element to add the Wysiwyg to.
|
|
19
|
+
* @param {Object} options - Options for the editor.
|
|
20
|
+
*/
|
|
21
|
+
constructor(element: HTMLElement, options: Partial<EdithOptions>);
|
|
22
|
+
on(type: string, listener: EventListenerOrEventListenerObject): void;
|
|
23
|
+
off(type: string, listener: EventListenerOrEventListenerObject): void;
|
|
24
|
+
trigger(type: Events, payload?: {
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}): void;
|
|
27
|
+
setContent(content: string): void;
|
|
28
|
+
getContent(): string;
|
|
29
|
+
destroy(): void;
|
|
30
|
+
}
|
package/dist/edith.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Events, addClass, createNodeWith, off, on, removeClass, trigger } from "./core/index.js";
|
|
2
|
+
import { DefaultOptions } from "./edith-options.js";
|
|
3
|
+
import { EdithButton, EdithButtons, EdithEditor } from "./ui/index.js";
|
|
4
|
+
export { EdithButton };
|
|
5
|
+
export class Edith {
|
|
6
|
+
element;
|
|
7
|
+
toolbar;
|
|
8
|
+
editor;
|
|
9
|
+
modals;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new editor
|
|
12
|
+
* @constructor
|
|
13
|
+
* @param {HTMLElement} element - The <input> element to add the Wysiwyg to.
|
|
14
|
+
* @param {Object} options - Options for the editor.
|
|
15
|
+
*/
|
|
16
|
+
constructor(element, options) {
|
|
17
|
+
// Render the editor in the element
|
|
18
|
+
this.element = element;
|
|
19
|
+
addClass(this.element, "edith");
|
|
20
|
+
// Create the toolbar
|
|
21
|
+
this.toolbar = createNodeWith("div", { attributes: { class: "edith-toolbar" } });
|
|
22
|
+
this.element.append(this.toolbar);
|
|
23
|
+
// Create buttons
|
|
24
|
+
const buttons = options.buttons ?? DefaultOptions.buttons;
|
|
25
|
+
const toolbar = options.toolbar ?? DefaultOptions.toolbar;
|
|
26
|
+
for (const { 0: group, 1: btns } of toolbar) {
|
|
27
|
+
// Create the button group
|
|
28
|
+
const btnGroup = document.createElement("div");
|
|
29
|
+
btnGroup.setAttribute("id", group);
|
|
30
|
+
btnGroup.setAttribute("class", "edith-btn-group");
|
|
31
|
+
this.toolbar.append(btnGroup);
|
|
32
|
+
// Add buttons
|
|
33
|
+
for (const btnId of btns) {
|
|
34
|
+
// Render the button
|
|
35
|
+
const buttonBuilder = buttons[btnId] ?? EdithButtons[btnId];
|
|
36
|
+
btnGroup.append(buttonBuilder(this).render());
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Create the editor
|
|
40
|
+
this.editor = new EdithEditor(this, {
|
|
41
|
+
initialContent: options.initialContent ?? DefaultOptions.initialContent,
|
|
42
|
+
height: options.height ?? DefaultOptions.height,
|
|
43
|
+
resizable: options.resizable ?? DefaultOptions.resizable,
|
|
44
|
+
});
|
|
45
|
+
this.element.append(this.editor.render());
|
|
46
|
+
// Create the modals
|
|
47
|
+
this.modals = createNodeWith("div", { attributes: { class: "edith-modals" } });
|
|
48
|
+
this.element.append(this.modals);
|
|
49
|
+
// Add the Edith instance to the DOM
|
|
50
|
+
this.element.edith = this;
|
|
51
|
+
// Trigger the initialized event once its initialized
|
|
52
|
+
this.trigger(Events.initialized);
|
|
53
|
+
}
|
|
54
|
+
on(type, listener) {
|
|
55
|
+
on(this.element, type, listener);
|
|
56
|
+
}
|
|
57
|
+
off(type, listener) {
|
|
58
|
+
off(this.element, type, listener);
|
|
59
|
+
}
|
|
60
|
+
trigger(type, payload) {
|
|
61
|
+
trigger(this.element, type, payload);
|
|
62
|
+
}
|
|
63
|
+
setContent(content) {
|
|
64
|
+
this.editor.setContent(content);
|
|
65
|
+
}
|
|
66
|
+
getContent() {
|
|
67
|
+
return this.editor.getContent();
|
|
68
|
+
}
|
|
69
|
+
destroy() {
|
|
70
|
+
removeClass(this.element, "edith");
|
|
71
|
+
this.modals.remove();
|
|
72
|
+
this.editor.destroy();
|
|
73
|
+
this.toolbar.remove();
|
|
74
|
+
this.element.remove();
|
|
75
|
+
}
|
|
76
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./edith.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./edith.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EdithButtonsOption } from "../edith-options.js";
|
|
2
|
+
import { Edith } from "../edith.js";
|
|
3
|
+
export type EdithButtonCallback = (ctx: Edith, event: Event) => void;
|
|
4
|
+
export declare class EdithButton {
|
|
5
|
+
private el;
|
|
6
|
+
private ctx;
|
|
7
|
+
private icon;
|
|
8
|
+
private title;
|
|
9
|
+
private onclick;
|
|
10
|
+
private showOnCodeView;
|
|
11
|
+
private popperEl;
|
|
12
|
+
private popper;
|
|
13
|
+
constructor(ctx: Edith, options: {
|
|
14
|
+
icon: string;
|
|
15
|
+
title: string;
|
|
16
|
+
onclick: EdithButtonCallback;
|
|
17
|
+
showOnCodeView?: boolean;
|
|
18
|
+
});
|
|
19
|
+
click(event: Event): void;
|
|
20
|
+
showTooltip(): void;
|
|
21
|
+
hideTooltip(): void;
|
|
22
|
+
onEditorModeChange(event: CustomEvent): void;
|
|
23
|
+
render(): HTMLButtonElement;
|
|
24
|
+
}
|
|
25
|
+
export declare const EdithButtons: Readonly<EdithButtonsOption>;
|