@lesjoursfr/edith 2.1.0 → 2.1.2
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/package.json +49 -32
- package/src/core/dom.ts +584 -0
- package/src/core/{edit.js → edit.ts} +59 -40
- package/src/core/events.ts +148 -0
- package/src/core/history.ts +28 -0
- package/src/core/index.ts +7 -0
- package/src/core/mode.ts +4 -0
- package/src/core/{range.js → range.ts} +32 -22
- package/src/core/{throttle.js → throttle.ts} +37 -23
- package/src/edith-options.ts +75 -0
- package/src/edith.ts +98 -0
- package/src/index.ts +1 -0
- package/src/ui/button.ts +197 -0
- package/src/ui/editor.ts +403 -0
- package/src/ui/index.ts +3 -0
- package/src/ui/modal.ts +180 -0
- package/src/core/dom.js +0 -353
- package/src/core/event.js +0 -4
- package/src/core/history.js +0 -27
- package/src/core/mode.js +0 -4
- package/src/index.js +0 -90
- package/src/ui/button.js +0 -200
- package/src/ui/editor.js +0 -392
- package/src/ui/modal.js +0 -151
- /package/src/css/{main.scss → edith.scss} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
/**
|
|
2
3
|
* Based on lodash version of throttle : https://github.com/lodash/lodash/blob/master/throttle.js
|
|
3
4
|
*/
|
|
@@ -22,48 +23,56 @@
|
|
|
22
23
|
* @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's invoked
|
|
23
24
|
* @returns {Function} Returns the new debounced function
|
|
24
25
|
*/
|
|
25
|
-
function debounce
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
function debounce<F extends (...args: any) => any>(
|
|
27
|
+
func: F,
|
|
28
|
+
wait: number,
|
|
29
|
+
options: { leading?: boolean; trailing?: boolean; maxWait?: number } = {}
|
|
30
|
+
): (...args: Parameters<F>) => ReturnType<F> {
|
|
31
|
+
let lastArgs: Parameters<F> | undefined,
|
|
32
|
+
lastThis: any | undefined,
|
|
33
|
+
result: ReturnType<F> | undefined,
|
|
34
|
+
timerId: ReturnType<typeof setTimeout> | undefined,
|
|
35
|
+
lastCallTime: number | undefined;
|
|
36
|
+
|
|
37
|
+
let lastInvokeTime: number = 0;
|
|
29
38
|
const leading = !!options.leading;
|
|
30
39
|
const maxing = "maxWait" in options;
|
|
31
|
-
const maxWait = maxing ? Math.max(
|
|
40
|
+
const maxWait = maxing ? Math.max(options.maxWait || 0, wait) : undefined;
|
|
32
41
|
const trailing = "trailing" in options ? !!options.trailing : true;
|
|
33
42
|
|
|
34
|
-
function invokeFunc(time) {
|
|
43
|
+
function invokeFunc(time: number): ReturnType<F> {
|
|
35
44
|
const args = lastArgs;
|
|
36
45
|
const thisArg = lastThis;
|
|
37
46
|
|
|
38
47
|
lastArgs = lastThis = undefined;
|
|
39
48
|
lastInvokeTime = time;
|
|
40
|
-
result = func.apply(thisArg
|
|
41
|
-
return result
|
|
49
|
+
result = func.apply(thisArg!, args!);
|
|
50
|
+
return result!;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
function startTimer(pendingFunc, wait) {
|
|
53
|
+
function startTimer(pendingFunc: () => void, wait: number): ReturnType<typeof setTimeout> {
|
|
45
54
|
return setTimeout(pendingFunc, wait);
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
function leadingEdge(time) {
|
|
57
|
+
function leadingEdge(time: number): ReturnType<F> {
|
|
49
58
|
// Reset any `maxWait` timer.
|
|
50
59
|
lastInvokeTime = time;
|
|
51
60
|
// Start the timer for the trailing edge.
|
|
52
61
|
timerId = startTimer(timerExpired, wait);
|
|
53
62
|
// Invoke the leading edge.
|
|
54
|
-
return leading ? invokeFunc(time) : result
|
|
63
|
+
return leading ? invokeFunc(time) : result!;
|
|
55
64
|
}
|
|
56
65
|
|
|
57
|
-
function remainingWait(time) {
|
|
58
|
-
const timeSinceLastCall = time - lastCallTime
|
|
66
|
+
function remainingWait(time: number): number {
|
|
67
|
+
const timeSinceLastCall = time - lastCallTime!;
|
|
59
68
|
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
60
69
|
const timeWaiting = wait - timeSinceLastCall;
|
|
61
70
|
|
|
62
|
-
return maxing ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
|
|
71
|
+
return maxing ? Math.min(timeWaiting, maxWait! - timeSinceLastInvoke) : timeWaiting;
|
|
63
72
|
}
|
|
64
73
|
|
|
65
|
-
function shouldInvoke(time) {
|
|
66
|
-
const timeSinceLastCall = time - lastCallTime
|
|
74
|
+
function shouldInvoke(time: number): boolean {
|
|
75
|
+
const timeSinceLastCall = time - lastCallTime!;
|
|
67
76
|
const timeSinceLastInvoke = time - lastInvokeTime;
|
|
68
77
|
|
|
69
78
|
// Either this is the first call, activity has stopped and we're at the
|
|
@@ -73,11 +82,11 @@ function debounce(func, wait, options = {}) {
|
|
|
73
82
|
lastCallTime === undefined ||
|
|
74
83
|
timeSinceLastCall >= wait ||
|
|
75
84
|
timeSinceLastCall < 0 ||
|
|
76
|
-
(maxing && timeSinceLastInvoke >= maxWait)
|
|
85
|
+
(maxing && timeSinceLastInvoke >= maxWait!)
|
|
77
86
|
);
|
|
78
87
|
}
|
|
79
88
|
|
|
80
|
-
function timerExpired() {
|
|
89
|
+
function timerExpired(): ReturnType<F> | undefined {
|
|
81
90
|
const time = Date.now();
|
|
82
91
|
if (shouldInvoke(time)) {
|
|
83
92
|
return trailingEdge(time);
|
|
@@ -86,7 +95,7 @@ function debounce(func, wait, options = {}) {
|
|
|
86
95
|
timerId = startTimer(timerExpired, remainingWait(time));
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
function trailingEdge(time) {
|
|
98
|
+
function trailingEdge(time: number): ReturnType<F> {
|
|
90
99
|
timerId = undefined;
|
|
91
100
|
|
|
92
101
|
// Only invoke if we have `lastArgs` which means `func` has been
|
|
@@ -95,14 +104,15 @@ function debounce(func, wait, options = {}) {
|
|
|
95
104
|
return invokeFunc(time);
|
|
96
105
|
}
|
|
97
106
|
lastArgs = lastThis = undefined;
|
|
98
|
-
return result
|
|
107
|
+
return result!;
|
|
99
108
|
}
|
|
100
109
|
|
|
101
|
-
function debounced(...args) {
|
|
110
|
+
function debounced(this: any, ...args: Parameters<F>): ReturnType<F> {
|
|
102
111
|
const time = Date.now();
|
|
103
112
|
const isInvoking = shouldInvoke(time);
|
|
104
113
|
|
|
105
114
|
lastArgs = args;
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
106
116
|
lastThis = this;
|
|
107
117
|
lastCallTime = time;
|
|
108
118
|
|
|
@@ -119,7 +129,7 @@ function debounce(func, wait, options = {}) {
|
|
|
119
129
|
if (timerId === undefined) {
|
|
120
130
|
timerId = startTimer(timerExpired, wait);
|
|
121
131
|
}
|
|
122
|
-
return result
|
|
132
|
+
return result!;
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
return debounced;
|
|
@@ -144,7 +154,11 @@ function debounce(func, wait, options = {}) {
|
|
|
144
154
|
* @param {boolean} [options.trailing=true] Specify invoking on the trailing edge of the timeout
|
|
145
155
|
* @returns {Function} Returns the new throttled function
|
|
146
156
|
*/
|
|
147
|
-
function throttle
|
|
157
|
+
function throttle<F extends (...args: any) => any>(
|
|
158
|
+
func: F,
|
|
159
|
+
wait: number,
|
|
160
|
+
options: { leading?: boolean; trailing?: boolean } = {}
|
|
161
|
+
): (...args: Parameters<F>) => ReturnType<F> {
|
|
148
162
|
const leading = "leading" in options ? !!options.leading : true;
|
|
149
163
|
const trailing = "trailing" in options ? !!options.trailing : true;
|
|
150
164
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Edith } from "./edith.js";
|
|
2
|
+
import { EdithButton } from "./ui/index.js";
|
|
3
|
+
|
|
4
|
+
export type EdithToolbarOption = [string, string[]][];
|
|
5
|
+
|
|
6
|
+
export type EdithButtonsOption = { [keyof: string]: (context: Edith) => EdithButton };
|
|
7
|
+
|
|
8
|
+
export type EdithOptions = {
|
|
9
|
+
height: number;
|
|
10
|
+
resizable: boolean;
|
|
11
|
+
toolbar: EdithToolbarOption;
|
|
12
|
+
buttons: EdithButtonsOption;
|
|
13
|
+
initialContent: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Edith default options
|
|
18
|
+
*/
|
|
19
|
+
export const DefaultOptions: EdithOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* The editor's height
|
|
22
|
+
*
|
|
23
|
+
* @type {number}
|
|
24
|
+
* @default 80
|
|
25
|
+
*/
|
|
26
|
+
height: 80,
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Control if the editor can be resized by the user
|
|
30
|
+
*
|
|
31
|
+
* @type {boolean}
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
resizable: false,
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* An array that define which button is shown in the toolbar and how they are grouped.
|
|
39
|
+
*
|
|
40
|
+
* @type {EdithToolbarOption}
|
|
41
|
+
* @example
|
|
42
|
+
* toolbar: [
|
|
43
|
+
* ["style", ["bold", "italic", "underline", "strikethrough"]],
|
|
44
|
+
* ["extra", ["subscript", "superscript"]]
|
|
45
|
+
* ]
|
|
46
|
+
*/
|
|
47
|
+
toolbar: [["style", ["bold", "italic", "underline", "strikethrough"]]],
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* Associative object with the button name and builder to create it.
|
|
52
|
+
*
|
|
53
|
+
* @type {EdithButtonsOption}
|
|
54
|
+
* @example
|
|
55
|
+
* buttons: {
|
|
56
|
+
* bold: (context: Edith) =>
|
|
57
|
+
* new EdithButton(context, {
|
|
58
|
+
* icon: "fa-solid fa-bold",
|
|
59
|
+
* title: "Gras",
|
|
60
|
+
* onclick: (ctx: Edith, event: Event) => {
|
|
61
|
+
* ctx.editor.wrapInsideTag("b");
|
|
62
|
+
* },
|
|
63
|
+
* }),
|
|
64
|
+
* }
|
|
65
|
+
*/
|
|
66
|
+
buttons: {},
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The editor's initial content
|
|
70
|
+
*
|
|
71
|
+
* @type {string}
|
|
72
|
+
* @default ""
|
|
73
|
+
*/
|
|
74
|
+
initialContent: "",
|
|
75
|
+
};
|
package/src/edith.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Events, addClass, createNodeWith, off, on, removeClass, trigger } from "./core/index.js";
|
|
2
|
+
import { DefaultOptions, EdithButtonsOption, EdithOptions, EdithToolbarOption } from "./edith-options.js";
|
|
3
|
+
import { EdithButton, EdithButtons, EdithEditor } from "./ui/index.js";
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
interface HTMLElement {
|
|
7
|
+
edith?: Edith;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { EdithButton };
|
|
12
|
+
|
|
13
|
+
export class Edith {
|
|
14
|
+
private readonly element: HTMLElement;
|
|
15
|
+
public readonly toolbar: HTMLDivElement;
|
|
16
|
+
public readonly editor: EdithEditor;
|
|
17
|
+
public readonly modals: HTMLDivElement;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Create a new editor
|
|
21
|
+
* @constructor
|
|
22
|
+
* @param {HTMLElement} element - The <input> element to add the Wysiwyg to.
|
|
23
|
+
* @param {Object} options - Options for the editor.
|
|
24
|
+
*/
|
|
25
|
+
constructor(element: HTMLElement, options: Partial<EdithOptions>) {
|
|
26
|
+
// Render the editor in the element
|
|
27
|
+
this.element = element;
|
|
28
|
+
addClass(this.element, "edith");
|
|
29
|
+
|
|
30
|
+
// Create the toolbar
|
|
31
|
+
this.toolbar = createNodeWith("div", { attributes: { class: "edith-toolbar" } });
|
|
32
|
+
this.element.append(this.toolbar);
|
|
33
|
+
|
|
34
|
+
// Create buttons
|
|
35
|
+
const buttons: EdithButtonsOption = options.buttons ?? DefaultOptions.buttons;
|
|
36
|
+
const toolbar: EdithToolbarOption = options.toolbar ?? DefaultOptions.toolbar;
|
|
37
|
+
for (const { 0: group, 1: btns } of toolbar) {
|
|
38
|
+
// Create the button group
|
|
39
|
+
const btnGroup = document.createElement("div");
|
|
40
|
+
btnGroup.setAttribute("id", group);
|
|
41
|
+
btnGroup.setAttribute("class", "edith-btn-group");
|
|
42
|
+
this.toolbar.append(btnGroup);
|
|
43
|
+
|
|
44
|
+
// Add buttons
|
|
45
|
+
for (const btnId of btns) {
|
|
46
|
+
// Render the button
|
|
47
|
+
const buttonBuilder = buttons[btnId] ?? EdithButtons[btnId];
|
|
48
|
+
btnGroup.append(buttonBuilder(this).render());
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Create the editor
|
|
53
|
+
this.editor = new EdithEditor(this, {
|
|
54
|
+
initialContent: options.initialContent ?? DefaultOptions.initialContent,
|
|
55
|
+
height: options.height ?? DefaultOptions.height,
|
|
56
|
+
resizable: options.resizable ?? DefaultOptions.resizable,
|
|
57
|
+
});
|
|
58
|
+
this.element.append(this.editor.render());
|
|
59
|
+
|
|
60
|
+
// Create the modals
|
|
61
|
+
this.modals = createNodeWith("div", { attributes: { class: "edith-modals" } });
|
|
62
|
+
this.element.append(this.modals);
|
|
63
|
+
|
|
64
|
+
// Add the Edith instance to the DOM
|
|
65
|
+
this.element.edith = this;
|
|
66
|
+
|
|
67
|
+
// Trigger the initialized event once its initialized
|
|
68
|
+
this.trigger(Events.initialized);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public on(type: string, listener: EventListenerOrEventListenerObject): void {
|
|
72
|
+
on(this.element, type, listener);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public off(type: string, listener: EventListenerOrEventListenerObject): void {
|
|
76
|
+
off(this.element, type, listener);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public trigger(type: Events, payload?: { [key: string]: unknown }): void {
|
|
80
|
+
trigger(this.element, type, payload);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public setContent(content: string): void {
|
|
84
|
+
this.editor.setContent(content);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public getContent(): string {
|
|
88
|
+
return this.editor.getContent();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public destroy(): void {
|
|
92
|
+
removeClass(this.element, "edith");
|
|
93
|
+
this.modals.remove();
|
|
94
|
+
this.editor.destroy();
|
|
95
|
+
this.toolbar.remove();
|
|
96
|
+
this.element.remove();
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./edith.js";
|
package/src/ui/button.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { createPopper } from "@popperjs/core";
|
|
2
|
+
import { EditorModes, Events, createNodeWith } from "../core/index.js";
|
|
3
|
+
import { EdithButtonsOption } from "../edith-options.js";
|
|
4
|
+
import { Edith } from "../edith.js";
|
|
5
|
+
|
|
6
|
+
export type EdithButtonCallback = (ctx: Edith, event: Event) => void;
|
|
7
|
+
|
|
8
|
+
export class EdithButton {
|
|
9
|
+
private el!: HTMLButtonElement;
|
|
10
|
+
private ctx: Edith;
|
|
11
|
+
private icon: string;
|
|
12
|
+
private title: string;
|
|
13
|
+
private onclick: EdithButtonCallback;
|
|
14
|
+
private showOnCodeView: boolean;
|
|
15
|
+
private popperEl: HTMLDivElement | undefined;
|
|
16
|
+
private popper: ReturnType<typeof createPopper> | undefined;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
ctx: Edith,
|
|
20
|
+
options: { icon: string; title: string; onclick: EdithButtonCallback; showOnCodeView?: boolean }
|
|
21
|
+
) {
|
|
22
|
+
this.ctx = ctx;
|
|
23
|
+
this.icon = options.icon;
|
|
24
|
+
this.title = options.title;
|
|
25
|
+
this.onclick = options.onclick;
|
|
26
|
+
this.showOnCodeView = options.showOnCodeView === true;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public click(event: Event): void {
|
|
30
|
+
// Prevent default
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
|
|
33
|
+
// Call the callback
|
|
34
|
+
this.onclick(this.ctx, event);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public showTooltip(): void {
|
|
38
|
+
if (this.popper !== undefined) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add the tooltip content to the DOM
|
|
43
|
+
this.popperEl = createNodeWith("div", {
|
|
44
|
+
textContent: this.title,
|
|
45
|
+
attributes: { class: "edith-tooltip" },
|
|
46
|
+
});
|
|
47
|
+
const arrowEl = createNodeWith("div", {
|
|
48
|
+
attributes: { class: "arrow", "data-popper-arrow": "" },
|
|
49
|
+
});
|
|
50
|
+
this.popperEl.append(arrowEl);
|
|
51
|
+
this.ctx.toolbar.append(this.popperEl);
|
|
52
|
+
|
|
53
|
+
// Create the tooltip
|
|
54
|
+
this.popper = createPopper(this.el, this.popperEl, {
|
|
55
|
+
placement: "bottom",
|
|
56
|
+
modifiers: [
|
|
57
|
+
{
|
|
58
|
+
name: "arrow",
|
|
59
|
+
options: {
|
|
60
|
+
padding: 5, // 5px from the edges of the popper
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "offset",
|
|
65
|
+
options: {
|
|
66
|
+
offset: [0, 8],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public hideTooltip(): void {
|
|
74
|
+
if (this.popper === undefined) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Destroy the tooltip
|
|
79
|
+
this.popper.destroy();
|
|
80
|
+
this.popper = undefined;
|
|
81
|
+
|
|
82
|
+
// Remove the tooltip content from the DOM
|
|
83
|
+
this.popperEl?.remove();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public onEditorModeChange(event: CustomEvent): void {
|
|
87
|
+
if (event.detail.mode === EditorModes.Code) {
|
|
88
|
+
this.el.setAttribute("disabled", "disabled");
|
|
89
|
+
} else {
|
|
90
|
+
this.el.removeAttribute("disabled");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public render(): HTMLButtonElement {
|
|
95
|
+
// Create the button
|
|
96
|
+
this.el = createNodeWith("button", {
|
|
97
|
+
attributes: { class: `edith-btn ${this.icon}`, type: "button" },
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Bind events
|
|
101
|
+
this.el.onclick = this.click.bind(this);
|
|
102
|
+
this.el.onmouseenter = this.showTooltip.bind(this);
|
|
103
|
+
this.el.onmouseleave = this.hideTooltip.bind(this);
|
|
104
|
+
|
|
105
|
+
// Check if we have to disable the button on the code view
|
|
106
|
+
if (this.showOnCodeView !== true) {
|
|
107
|
+
this.ctx.on(Events.modeChanged, this.onEditorModeChange.bind(this) as EventListener);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Return the button
|
|
111
|
+
return this.el;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const EdithButtons = Object.freeze({
|
|
116
|
+
bold: (context: Edith) =>
|
|
117
|
+
new EdithButton(context, {
|
|
118
|
+
icon: "fa-solid fa-bold",
|
|
119
|
+
title: "Gras",
|
|
120
|
+
onclick: (ctx: Edith) => {
|
|
121
|
+
ctx.editor.wrapInsideTag("b");
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
italic: (context: Edith) =>
|
|
125
|
+
new EdithButton(context, {
|
|
126
|
+
icon: "fa-solid fa-italic",
|
|
127
|
+
title: "Italique",
|
|
128
|
+
onclick: (ctx: Edith) => {
|
|
129
|
+
ctx.editor.wrapInsideTag("i");
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
underline: (context: Edith) =>
|
|
133
|
+
new EdithButton(context, {
|
|
134
|
+
icon: "fa-solid fa-underline",
|
|
135
|
+
title: "Souligner",
|
|
136
|
+
onclick: (ctx: Edith) => {
|
|
137
|
+
ctx.editor.wrapInsideTag("u");
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
140
|
+
strikethrough: (context: Edith) =>
|
|
141
|
+
new EdithButton(context, {
|
|
142
|
+
icon: "fa-solid fa-strikethrough",
|
|
143
|
+
title: "Barrer",
|
|
144
|
+
onclick: (ctx: Edith) => {
|
|
145
|
+
ctx.editor.wrapInsideTag("s");
|
|
146
|
+
},
|
|
147
|
+
}),
|
|
148
|
+
subscript: (context: Edith) =>
|
|
149
|
+
new EdithButton(context, {
|
|
150
|
+
icon: "fa-solid fa-subscript",
|
|
151
|
+
title: "Indice",
|
|
152
|
+
onclick: (ctx: Edith) => {
|
|
153
|
+
ctx.editor.wrapInsideTag("sub");
|
|
154
|
+
},
|
|
155
|
+
}),
|
|
156
|
+
superscript: (context: Edith) =>
|
|
157
|
+
new EdithButton(context, {
|
|
158
|
+
icon: "fa-solid fa-superscript",
|
|
159
|
+
title: "Exposant",
|
|
160
|
+
onclick: (ctx: Edith) => {
|
|
161
|
+
ctx.editor.wrapInsideTag("sup");
|
|
162
|
+
},
|
|
163
|
+
}),
|
|
164
|
+
nbsp: (context: Edith) =>
|
|
165
|
+
new EdithButton(context, {
|
|
166
|
+
icon: "edith-btn-nbsp",
|
|
167
|
+
title: "Ajouter une espace insécable",
|
|
168
|
+
onclick: (ctx: Edith) => {
|
|
169
|
+
ctx.editor.replaceByHtml('<span class="edith-nbsp" contenteditable="false">¶</span>');
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
clear: (context: Edith) =>
|
|
173
|
+
new EdithButton(context, {
|
|
174
|
+
icon: "fa-solid fa-eraser",
|
|
175
|
+
title: "Effacer la mise en forme",
|
|
176
|
+
onclick: (ctx: Edith) => {
|
|
177
|
+
ctx.editor.clearStyle();
|
|
178
|
+
},
|
|
179
|
+
}),
|
|
180
|
+
link: (context: Edith) =>
|
|
181
|
+
new EdithButton(context, {
|
|
182
|
+
icon: "fa-solid fa-link",
|
|
183
|
+
title: "Lien",
|
|
184
|
+
onclick: (ctx: Edith) => {
|
|
185
|
+
ctx.editor.insertLink();
|
|
186
|
+
},
|
|
187
|
+
}),
|
|
188
|
+
codeview: (context: Edith) =>
|
|
189
|
+
new EdithButton(context, {
|
|
190
|
+
icon: "fa-solid fa-code",
|
|
191
|
+
title: "Afficher le code HTML",
|
|
192
|
+
onclick: (ctx: Edith) => {
|
|
193
|
+
ctx.editor.toggleCodeView();
|
|
194
|
+
},
|
|
195
|
+
showOnCodeView: true,
|
|
196
|
+
}),
|
|
197
|
+
} as EdithButtonsOption);
|