tiny-markdown-editor 0.1.33 → 0.2.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.
@@ -0,0 +1,35 @@
1
+ import { Editor, Position } from "./TinyMDE";
2
+ export interface CommandAction {
3
+ (editor: Editor): void;
4
+ }
5
+ export interface CommandEnabled {
6
+ (editor: Editor, focus?: Position, anchor?: Position): boolean | null;
7
+ }
8
+ export interface CommandDefinition {
9
+ name: string;
10
+ action: string | CommandAction;
11
+ innerHTML: string;
12
+ title: string;
13
+ hotkey?: string;
14
+ enabled?: CommandEnabled;
15
+ }
16
+ export interface CommandBarProps {
17
+ element?: string | HTMLElement;
18
+ editor?: Editor;
19
+ commands?: (string | CommandDefinition)[];
20
+ }
21
+ export declare class CommandBar {
22
+ e: HTMLDivElement | null;
23
+ editor: Editor | null;
24
+ commands: Record<string, CommandDefinition>;
25
+ buttons: Record<string, HTMLDivElement>;
26
+ state: Record<string, boolean | null>;
27
+ private hotkeys;
28
+ constructor(props: CommandBarProps);
29
+ private createCommandBarElement;
30
+ private handleClick;
31
+ setEditor(editor: Editor): void;
32
+ private handleSelection;
33
+ private handleKeydown;
34
+ }
35
+ export default CommandBar;
@@ -1,278 +1,329 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
- var _svg = _interopRequireDefault(require("./svg/svg"));
8
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CommandBar = void 0;
7
+ const svg_1 = __importDefault(require("./svg/svg"));
9
8
  const isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(typeof navigator !== "undefined" ? navigator.platform : "");
10
9
  const DefaultCommands = {
11
- bold: {
12
- name: "bold",
13
- action: "bold",
14
- innerHTML: _svg.default.bold,
15
- title: "Bold",
16
- hotkey: "Mod-B"
17
- },
18
- italic: {
19
- name: "italic",
20
- action: "italic",
21
- innerHTML: _svg.default.italic,
22
- title: "Italic",
23
- hotkey: "Mod-I"
24
- },
25
- strikethrough: {
26
- name: "strikethrough",
27
- action: "strikethrough",
28
- innerHTML: _svg.default.strikethrough,
29
- title: "Strikethrough",
30
- hotkey: "Mod2-Shift-5"
31
- },
32
- code: {
33
- name: "code",
34
- action: "code",
35
- innerHTML: _svg.default.code,
36
- title: "Format as code"
37
- },
38
- h1: {
39
- name: "h1",
40
- action: "h1",
41
- innerHTML: _svg.default.h1,
42
- title: "Level 1 heading",
43
- hotkey: "Mod-Shift-1"
44
- },
45
- h2: {
46
- name: "h2",
47
- action: "h2",
48
- innerHTML: _svg.default.h2,
49
- title: "Level 2 heading",
50
- hotkey: "Mod-Shift-2"
51
- },
52
- ul: {
53
- name: "ul",
54
- action: "ul",
55
- innerHTML: _svg.default.ul,
56
- title: "Bulleted list"
57
- },
58
- ol: {
59
- name: "ol",
60
- action: "ol",
61
- innerHTML: _svg.default.ol,
62
- title: "Numbered list"
63
- },
64
- blockquote: {
65
- name: "blockquote",
66
- action: "blockquote",
67
- innerHTML: _svg.default.blockquote,
68
- title: "Quote",
69
- hotkey: "Mod2-Shift-Q"
70
- },
71
- insertLink: {
72
- name: "insertLink",
73
- action: editor => {
74
- if (editor.isInlineFormattingAllowed()) editor.wrapSelection("[", "]()");
10
+ bold: {
11
+ name: "bold",
12
+ action: "bold",
13
+ innerHTML: svg_1.default.bold,
14
+ title: "Bold",
15
+ hotkey: "Mod-B",
16
+ },
17
+ italic: {
18
+ name: "italic",
19
+ action: "italic",
20
+ innerHTML: svg_1.default.italic,
21
+ title: "Italic",
22
+ hotkey: "Mod-I",
23
+ },
24
+ strikethrough: {
25
+ name: "strikethrough",
26
+ action: "strikethrough",
27
+ innerHTML: svg_1.default.strikethrough,
28
+ title: "Strikethrough",
29
+ hotkey: "Mod2-Shift-5",
30
+ },
31
+ code: {
32
+ name: "code",
33
+ action: "code",
34
+ innerHTML: svg_1.default.code,
35
+ title: "Format as code",
36
+ },
37
+ h1: {
38
+ name: "h1",
39
+ action: "h1",
40
+ innerHTML: svg_1.default.h1,
41
+ title: "Level 1 heading",
42
+ hotkey: "Mod-Shift-1",
43
+ },
44
+ h2: {
45
+ name: "h2",
46
+ action: "h2",
47
+ innerHTML: svg_1.default.h2,
48
+ title: "Level 2 heading",
49
+ hotkey: "Mod-Shift-2",
50
+ },
51
+ ul: {
52
+ name: "ul",
53
+ action: "ul",
54
+ innerHTML: svg_1.default.ul,
55
+ title: "Bulleted list",
56
+ },
57
+ ol: {
58
+ name: "ol",
59
+ action: "ol",
60
+ innerHTML: svg_1.default.ol,
61
+ title: "Numbered list",
62
+ },
63
+ blockquote: {
64
+ name: "blockquote",
65
+ action: "blockquote",
66
+ innerHTML: svg_1.default.blockquote,
67
+ title: "Quote",
68
+ hotkey: "Mod2-Shift-Q",
75
69
  },
76
- enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
77
- innerHTML: _svg.default.link,
78
- title: "Insert link",
79
- hotkey: "Mod-K"
80
- },
81
- insertImage: {
82
- name: "insertImage",
83
- action: editor => {
84
- if (editor.isInlineFormattingAllowed()) editor.wrapSelection("![", "]()");
70
+ insertLink: {
71
+ name: "insertLink",
72
+ action: (editor) => {
73
+ if (editor.isInlineFormattingAllowed())
74
+ editor.wrapSelection("[", "]()");
75
+ },
76
+ enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
77
+ innerHTML: svg_1.default.link,
78
+ title: "Insert link",
79
+ hotkey: "Mod-K",
80
+ },
81
+ insertImage: {
82
+ name: "insertImage",
83
+ action: (editor) => {
84
+ if (editor.isInlineFormattingAllowed())
85
+ editor.wrapSelection("![", "]()");
86
+ },
87
+ enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
88
+ innerHTML: svg_1.default.image,
89
+ title: "Insert image",
90
+ hotkey: "Mod2-Shift-I",
91
+ },
92
+ hr: {
93
+ name: "hr",
94
+ action: (editor) => editor.paste("\n***\n"),
95
+ enabled: () => false,
96
+ innerHTML: svg_1.default.hr,
97
+ title: "Insert horizontal line",
98
+ hotkey: "Mod2-Shift-L",
99
+ },
100
+ undo: {
101
+ name: "undo",
102
+ action: (editor) => editor.undo(),
103
+ enabled: (editor) => (editor.canUndo ? false : null),
104
+ innerHTML: svg_1.default.undo,
105
+ title: "Undo",
106
+ },
107
+ redo: {
108
+ name: "redo",
109
+ action: (editor) => editor.redo(),
110
+ enabled: (editor) => (editor.canRedo ? false : null),
111
+ innerHTML: svg_1.default.redo,
112
+ title: "Redo",
85
113
  },
86
- enabled: (editor, focus, anchor) => editor.isInlineFormattingAllowed(focus, anchor) ? false : null,
87
- innerHTML: _svg.default.image,
88
- title: "Insert image",
89
- hotkey: "Mod2-Shift-I"
90
- },
91
- hr: {
92
- name: "hr",
93
- action: editor => editor.paste("\n***\n"),
94
- enabled: () => false,
95
- innerHTML: _svg.default.hr,
96
- title: "Insert horizontal line",
97
- hotkey: "Mod2-Shift-L"
98
- },
99
- undo: {
100
- name: "undo",
101
- action: editor => editor.undo(),
102
- enabled: editor => editor.canUndo ? false : null,
103
- innerHTML: _svg.default.undo,
104
- title: "Undo"
105
- },
106
- redo: {
107
- name: "redo",
108
- action: editor => editor.redo(),
109
- enabled: editor => editor.canRedo ? false : null,
110
- innerHTML: _svg.default.redo,
111
- title: "Redo"
112
- }
113
114
  };
114
115
  class CommandBar {
115
- constructor(props) {
116
- this.e = null;
117
- this.editor = null;
118
- this.commands = [];
119
- this.buttons = {};
120
- this.state = {};
121
- this.hotkeys = [];
122
- let element = props.element;
123
- if (element && !element.tagName) {
124
- element = document.getElementById(props.element);
125
- }
126
- if (!element) {
127
- element = document.body;
128
- }
129
- this.createCommandBarElement(element, props.commands || ["bold", "italic", "strikethrough", "|", "code", "|", "h1", "h2", "|", "ul", "ol", "|", "blockquote", "hr", "|", "undo", "redo", "|", "insertLink", "insertImage"]);
130
- document.addEventListener("keydown", e => this.handleKeydown(e));
131
- if (props.editor) this.setEditor(props.editor);
132
- }
133
- createCommandBarElement(parentElement, commands) {
134
- this.e = document.createElement("div");
135
- this.e.className = "TMCommandBar";
136
- for (let command of commands) {
137
- if (command == "|") {
138
- let el = document.createElement("div");
139
- el.className = "TMCommandDivider";
140
- this.e.appendChild(el);
141
- } else {
142
- let commandName;
143
- if (typeof command == "string") {
144
- // Reference to default command
145
-
146
- if (DefaultCommands[command]) {
147
- commandName = command;
148
- this.commands[commandName] = DefaultCommands[commandName];
149
- } else {
150
- continue;
151
- }
152
- } else if (typeof command == "object" && command.name) {
153
- commandName = command.name;
154
- this.commands[commandName] = {};
155
- if (DefaultCommands[commandName]) Object.assign(this.commands[commandName], DefaultCommands[commandName]);
156
- Object.assign(this.commands[commandName], command);
157
- } else {
158
- continue;
116
+ constructor(props) {
117
+ this.e = null;
118
+ this.editor = null;
119
+ this.commands = {};
120
+ this.buttons = {};
121
+ this.state = {};
122
+ this.hotkeys = [];
123
+ this.e = null;
124
+ this.editor = null;
125
+ this.commands = {};
126
+ this.buttons = {};
127
+ this.state = {};
128
+ this.hotkeys = [];
129
+ let element = null;
130
+ if (typeof props.element === 'string') {
131
+ element = document.getElementById(props.element);
132
+ }
133
+ else if (props.element) {
134
+ element = props.element;
135
+ }
136
+ if (!element) {
137
+ element = document.body;
159
138
  }
160
- let title = this.commands[commandName].title || commandName;
161
- if (this.commands[commandName].hotkey) {
162
- const keys = this.commands[commandName].hotkey.split("-");
163
- // construct modifiers
164
- let modifiers = [];
165
- let modifierexplanation = [];
166
- for (let i = 0; i < keys.length - 1; i++) {
167
- switch (keys[i]) {
168
- case "Ctrl":
169
- modifiers.push("ctrlKey");
170
- modifierexplanation.push("Ctrl");
171
- break;
172
- case "Cmd":
173
- modifiers.push("metaKey");
174
- modifierexplanation.push("");
175
- break;
176
- case "Alt":
177
- modifiers.push("altKey");
178
- modifierexplanation.push("Alt");
179
- break;
180
- case "Option":
181
- modifiers.push("altKey");
182
- modifierexplanation.push("");
183
- break;
184
- case "Win":
185
- modifiers.push("metaKey");
186
- modifierexplanation.push("⊞ Win");
187
- break;
188
- case "Shift":
189
- modifiers.push("shiftKey");
190
- modifierexplanation.push("");
191
- break;
192
- case "Mod":
193
- // Mod is a convenience mechanism: Ctrl on Windows, Cmd on Mac
194
- if (isMacLike) {
195
- modifiers.push("metaKey");
196
- modifierexplanation.push("⌘");
197
- } else {
198
- modifiers.push("ctrlKey");
199
- modifierexplanation.push("Ctrl");
139
+ this.createCommandBarElement(element, props.commands || [
140
+ "bold",
141
+ "italic",
142
+ "strikethrough",
143
+ "|",
144
+ "code",
145
+ "|",
146
+ "h1",
147
+ "h2",
148
+ "|",
149
+ "ul",
150
+ "ol",
151
+ "|",
152
+ "blockquote",
153
+ "hr",
154
+ "|",
155
+ "undo",
156
+ "redo",
157
+ "|",
158
+ "insertLink",
159
+ "insertImage",
160
+ ]);
161
+ document.addEventListener("keydown", (e) => this.handleKeydown(e));
162
+ if (props.editor)
163
+ this.setEditor(props.editor);
164
+ }
165
+ createCommandBarElement(parentElement, commands) {
166
+ this.e = document.createElement("div");
167
+ this.e.className = "TMCommandBar";
168
+ for (let command of commands) {
169
+ if (command === "|") {
170
+ let el = document.createElement("div");
171
+ el.className = "TMCommandDivider";
172
+ this.e.appendChild(el);
173
+ }
174
+ else {
175
+ let commandName;
176
+ if (typeof command === "string") {
177
+ if (DefaultCommands[command]) {
178
+ commandName = command;
179
+ this.commands[commandName] = DefaultCommands[commandName];
180
+ }
181
+ else {
182
+ continue;
183
+ }
184
+ }
185
+ else if (typeof command === "object" && command.name) {
186
+ commandName = command.name;
187
+ this.commands[commandName] = {};
188
+ if (DefaultCommands[commandName]) {
189
+ Object.assign(this.commands[commandName], DefaultCommands[commandName]);
190
+ }
191
+ Object.assign(this.commands[commandName], command);
192
+ }
193
+ else {
194
+ continue;
195
+ }
196
+ let title = this.commands[commandName].title || commandName;
197
+ if (this.commands[commandName].hotkey) {
198
+ const keys = this.commands[commandName].hotkey.split("-");
199
+ let modifiers = [];
200
+ let modifierexplanation = [];
201
+ for (let i = 0; i < keys.length - 1; i++) {
202
+ switch (keys[i]) {
203
+ case "Ctrl":
204
+ modifiers.push("ctrlKey");
205
+ modifierexplanation.push("Ctrl");
206
+ break;
207
+ case "Cmd":
208
+ modifiers.push("metaKey");
209
+ modifierexplanation.push("⌘");
210
+ break;
211
+ case "Alt":
212
+ modifiers.push("altKey");
213
+ modifierexplanation.push("Alt");
214
+ break;
215
+ case "Option":
216
+ modifiers.push("altKey");
217
+ modifierexplanation.push("⌥");
218
+ break;
219
+ case "Win":
220
+ modifiers.push("metaKey");
221
+ modifierexplanation.push("⊞ Win");
222
+ break;
223
+ case "Shift":
224
+ modifiers.push("shiftKey");
225
+ modifierexplanation.push("⇧");
226
+ break;
227
+ case "Mod":
228
+ if (isMacLike) {
229
+ modifiers.push("metaKey");
230
+ modifierexplanation.push("⌘");
231
+ }
232
+ else {
233
+ modifiers.push("ctrlKey");
234
+ modifierexplanation.push("Ctrl");
235
+ }
236
+ break;
237
+ case "Mod2":
238
+ modifiers.push("altKey");
239
+ if (isMacLike)
240
+ modifierexplanation.push("⌥");
241
+ else
242
+ modifierexplanation.push("Alt");
243
+ break;
244
+ }
245
+ }
246
+ modifierexplanation.push(keys[keys.length - 1]);
247
+ let hotkey = {
248
+ modifiers: modifiers,
249
+ command: commandName,
250
+ };
251
+ if (keys[keys.length - 1].match(/^[0-9]$/)) {
252
+ hotkey.code = `Digit${keys[keys.length - 1]}`;
253
+ }
254
+ else {
255
+ hotkey.key = keys[keys.length - 1].toLowerCase();
256
+ }
257
+ this.hotkeys.push(hotkey);
258
+ title = title.concat(` (${modifierexplanation.join("+")})`);
200
259
  }
201
- break;
202
- case "Mod2":
203
- modifiers.push("altKey");
204
- if (isMacLike) modifierexplanation.push("⌥");else modifierexplanation.push("Alt");
205
- break;
206
- // Mod2 is a convenience mechanism: Alt on Windows, Option on Mac
260
+ this.buttons[commandName] = document.createElement("div");
261
+ this.buttons[commandName].className = "TMCommandButton TMCommandButton_Disabled";
262
+ this.buttons[commandName].title = title;
263
+ this.buttons[commandName].innerHTML = this.commands[commandName].innerHTML;
264
+ this.buttons[commandName].addEventListener("mousedown", (e) => this.handleClick(commandName, e));
265
+ this.e.appendChild(this.buttons[commandName]);
207
266
  }
208
- }
209
- modifierexplanation.push(keys[keys.length - 1]);
210
- let hotkey = {
211
- modifiers: modifiers,
212
- command: commandName
213
- };
214
- // TODO Right now this is working only for letters and numbers
215
- if (keys[keys.length - 1].match(/^[0-9]$/)) {
216
- hotkey.code = `Digit${keys[keys.length - 1]}`;
217
- } else {
218
- hotkey.key = keys[keys.length - 1].toLowerCase();
219
- }
220
- this.hotkeys.push(hotkey);
221
- title = title.concat(` (${modifierexplanation.join("+")})`);
222
267
  }
223
- this.buttons[commandName] = document.createElement("div");
224
- this.buttons[commandName].className = "TMCommandButton TMCommandButton_Disabled";
225
- this.buttons[commandName].title = title;
226
- this.buttons[commandName].innerHTML = this.commands[commandName].innerHTML;
227
- this.buttons[commandName].addEventListener("mousedown", e => this.handleClick(commandName, e));
228
- this.e.appendChild(this.buttons[commandName]);
229
- }
268
+ parentElement.appendChild(this.e);
230
269
  }
231
- parentElement.appendChild(this.e);
232
- }
233
- handleClick(commandName, event) {
234
- if (!this.editor) return;
235
- event.preventDefault();
236
- if (typeof this.commands[commandName].action == "string") {
237
- if (this.state[commandName] === false) this.editor.setCommandState(commandName, true);else this.editor.setCommandState(commandName, false);
238
- } else if (typeof this.commands[commandName].action == "function") {
239
- this.commands[commandName].action(this.editor);
240
- }
241
- }
242
- setEditor(editor) {
243
- this.editor = editor;
244
- editor.addEventListener("selection", e => this.handleSelection(e));
245
- }
246
- handleSelection(event) {
247
- if (event.commandState) {
248
- for (let command in this.commands) {
249
- if (event.commandState[command] === undefined) {
250
- if (this.commands[command].enabled) this.state[command] = this.commands[command].enabled(this.editor, event.focus, event.anchor);else this.state[command] = event.focus ? false : null;
251
- } else {
252
- this.state[command] = event.commandState[command];
270
+ handleClick(commandName, event) {
271
+ if (!this.editor)
272
+ return;
273
+ event.preventDefault();
274
+ if (typeof this.commands[commandName].action === "string") {
275
+ if (this.state[commandName] === false)
276
+ this.editor.setCommandState(commandName, true);
277
+ else
278
+ this.editor.setCommandState(commandName, false);
253
279
  }
254
- if (this.state[command] === true) {
255
- this.buttons[command].className = "TMCommandButton TMCommandButton_Active";
256
- } else if (this.state[command] === false) {
257
- this.buttons[command].className = "TMCommandButton TMCommandButton_Inactive";
258
- } else {
259
- this.buttons[command].className = "TMCommandButton TMCommandButton_Disabled";
280
+ else if (typeof this.commands[commandName].action === "function") {
281
+ this.commands[commandName].action(this.editor);
260
282
  }
261
- }
262
283
  }
263
- }
264
- handleKeydown(event) {
265
- outer: for (let hotkey of this.hotkeys) {
266
- if (hotkey.key && event.key.toLowerCase() == hotkey.key || hotkey.code && event.code == hotkey.code) {
267
- // Key matches hotkey. Look for any required modifier that wasn't pressed
268
- for (let modifier of hotkey.modifiers) {
269
- if (!event[modifier]) continue outer;
284
+ setEditor(editor) {
285
+ this.editor = editor;
286
+ editor.addEventListener("selection", (e) => this.handleSelection(e));
287
+ }
288
+ handleSelection(event) {
289
+ if (event.commandState) {
290
+ for (let command in this.commands) {
291
+ if (event.commandState[command] === undefined) {
292
+ if (this.commands[command].enabled) {
293
+ this.state[command] = this.commands[command].enabled(this.editor, event.focus, event.anchor);
294
+ }
295
+ else {
296
+ this.state[command] = event.focus ? false : null;
297
+ }
298
+ }
299
+ else {
300
+ this.state[command] = event.commandState[command];
301
+ }
302
+ if (this.state[command] === true) {
303
+ this.buttons[command].className = "TMCommandButton TMCommandButton_Active";
304
+ }
305
+ else if (this.state[command] === false) {
306
+ this.buttons[command].className = "TMCommandButton TMCommandButton_Inactive";
307
+ }
308
+ else {
309
+ this.buttons[command].className = "TMCommandButton TMCommandButton_Disabled";
310
+ }
311
+ }
312
+ }
313
+ }
314
+ handleKeydown(event) {
315
+ outer: for (let hotkey of this.hotkeys) {
316
+ if ((hotkey.key && event.key.toLowerCase() === hotkey.key) ||
317
+ (hotkey.code && event.code === hotkey.code)) {
318
+ for (let modifier of hotkey.modifiers) {
319
+ if (!event[modifier])
320
+ continue outer;
321
+ }
322
+ this.handleClick(hotkey.command, event);
323
+ return;
324
+ }
270
325
  }
271
- // Everything matches.
272
- this.handleClick(hotkey.command, event);
273
- return;
274
- }
275
326
  }
276
- }
277
327
  }
278
- var _default = exports.default = CommandBar;
328
+ exports.CommandBar = CommandBar;
329
+ exports.default = CommandBar;