markdown-text-editor 0.1.5 → 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.
- package/README.md +114 -61
- package/dist/index.css +2 -7
- package/dist/index.css.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown-text-editor.css +2 -7
- package/dist/markdown-text-editor.css.map +1 -1
- package/dist/markdown-text-editor.js +1 -1
- package/dist/markdown-text-editor.js.map +1 -1
- package/package.json +14 -15
- package/src/plugins/index.js +0 -2
- package/src/plugins/markdown/Toolbar/MakeTool.js +0 -22
- package/src/plugins/markdown/Toolbar/index.js +0 -56
- package/src/plugins/markdown/Toolbar/tools/BlockQuoteTool.js +0 -31
- package/src/plugins/markdown/Toolbar/tools/BoldTool.js +0 -33
- package/src/plugins/markdown/Toolbar/tools/CheckListTool.js +0 -31
- package/src/plugins/markdown/Toolbar/tools/HeadingTool.js +0 -55
- package/src/plugins/markdown/Toolbar/tools/ItalicTool.js +0 -31
- package/src/plugins/markdown/Toolbar/tools/LinkTool.js +0 -47
- package/src/plugins/markdown/Toolbar/tools/OLTool.js +0 -31
- package/src/plugins/markdown/Toolbar/tools/PreviewTool.js +0 -108
- package/src/plugins/markdown/Toolbar/tools/StrikethroughTool.js +0 -31
- package/src/plugins/markdown/Toolbar/tools/ULTool.js +0 -31
- package/src/plugins/markdown/editor.js +0 -172
- package/src/plugins/markdown/preview.js +0 -17
- package/src/plugins/markdown/styles/main.css +0 -21
- package/src/plugins/markdown/utils/markdownUtils.js +0 -7
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdown-text-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A simple JavaScript Markdown editor plugin with real-time preview, and easy integration.",
|
|
5
5
|
"main": "./dist/markdown-text-editor.js",
|
|
6
6
|
"browser": "dist/markdown-text-editor.js",
|
|
7
7
|
"style": "./dist/markdown-text-editor.css",
|
|
8
8
|
"files": [
|
|
9
|
-
"dist/**/*"
|
|
10
|
-
"src/**/*"
|
|
9
|
+
"dist/**/*"
|
|
11
10
|
],
|
|
12
11
|
"repository": {
|
|
13
12
|
"type": "git",
|
|
@@ -57,26 +56,26 @@
|
|
|
57
56
|
"url": "https://github.com/nezanuha/markdown-text-editor/issues"
|
|
58
57
|
},
|
|
59
58
|
"dependencies": {
|
|
60
|
-
"marked": "~15.0.
|
|
59
|
+
"marked": "~15.0.11"
|
|
61
60
|
},
|
|
62
61
|
"devDependencies": {
|
|
63
|
-
"@babel/core": "^7.
|
|
64
|
-
"@babel/preset-env": "^7.
|
|
65
|
-
"@tailwindcss/postcss": "^4.
|
|
66
|
-
"@tailwindcss/typography": "^0.5.
|
|
62
|
+
"@babel/core": "^7.27.1",
|
|
63
|
+
"@babel/preset-env": "^7.27.2",
|
|
64
|
+
"@tailwindcss/postcss": "^4.1.6",
|
|
65
|
+
"@tailwindcss/typography": "^0.5.16",
|
|
67
66
|
"babel-loader": "^10.0.0",
|
|
68
67
|
"css-loader": "^7.1.2",
|
|
69
|
-
"
|
|
68
|
+
"frutjam": "^0.8.1-beta.3",
|
|
70
69
|
"html-webpack-plugin": "^5.6.3",
|
|
71
|
-
"mini-css-extract-plugin": "^2.9.
|
|
72
|
-
"postcss": "^8.
|
|
70
|
+
"mini-css-extract-plugin": "^2.9.2",
|
|
71
|
+
"postcss": "^8.5.3",
|
|
73
72
|
"postcss-loader": "^8.1.1",
|
|
74
73
|
"rimraf": "^6.0.1",
|
|
75
74
|
"style-loader": "^4.0.0",
|
|
76
|
-
"tailwindcss": "^4.
|
|
77
|
-
"terser-webpack-plugin": "^5.3.
|
|
78
|
-
"webpack": "^5.
|
|
75
|
+
"tailwindcss": "^4.1.6",
|
|
76
|
+
"terser-webpack-plugin": "^5.3.14",
|
|
77
|
+
"webpack": "^5.99.8",
|
|
79
78
|
"webpack-cli": "^6.0.1",
|
|
80
|
-
"webpack-dev-server": "^5.2.
|
|
79
|
+
"webpack-dev-server": "^5.2.1"
|
|
81
80
|
}
|
|
82
81
|
}
|
package/src/plugins/index.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
class MakeTool {
|
|
2
|
-
constructor(editor, title) {
|
|
3
|
-
this.editor = editor;
|
|
4
|
-
this.defaultText = `${title} text`; // Default text if nothing is selected
|
|
5
|
-
this.button = this.createButton();
|
|
6
|
-
this.title = title
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// Create a button element (can be overridden in child classes)
|
|
10
|
-
createButton(iconHtml) {
|
|
11
|
-
const button = document.createElement('button');
|
|
12
|
-
const buttonClass = this.title ? `${this.title.replace(/ /g, '-')}-btn`.toLowerCase() : '';
|
|
13
|
-
button.innerHTML = iconHtml; // Pass icon HTML from child classes
|
|
14
|
-
button.type = 'button';
|
|
15
|
-
button.title = this.title;
|
|
16
|
-
button.className = `markdown-btn ${buttonClass}${buttonClass == 'preview-btn' ? ' sticky right-0 bg-stone-100 dark:bg-stone-900 ' : ' ' }p-2 hover:bg-stone-200 dark:hover:bg-stone-600 rounded-sm duration-300 text-stone-900 dark:text-stone-100`;
|
|
17
|
-
button.addEventListener('click', () => this.applySyntax()); // Default to 'both', can change in child
|
|
18
|
-
return button;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default MakeTool;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// #markdown\Toolbar\index.js
|
|
2
|
-
import BoldTool from './tools/BoldTool.js';
|
|
3
|
-
import ItalicTool from './tools/ItalicTool.js';
|
|
4
|
-
import StrikethroughTool from './tools/StrikethroughTool.js';
|
|
5
|
-
import ULTool from './tools/ULTool.js';
|
|
6
|
-
import OLTool from './tools/OLTool.js';
|
|
7
|
-
import PreviewTool from './tools/PreviewTool.js'
|
|
8
|
-
import CheckListTool from './tools/CheckListTool.js';
|
|
9
|
-
import BlockQuoteTool from './tools/BlockQuoteTool.js';
|
|
10
|
-
import LinkTool from './tools/LinkTool.js'
|
|
11
|
-
import HeadingTool from './tools/HeadingTool.js';
|
|
12
|
-
|
|
13
|
-
class Toolbar {
|
|
14
|
-
constructor(editor, options) {
|
|
15
|
-
this.editor = editor;
|
|
16
|
-
this.options = options;
|
|
17
|
-
this.toolbar = document.createElement('div');
|
|
18
|
-
this.toolbar.className = 'toolbar flex space-x-1.5 p-1.5 bg-stone-100 dark:bg-stone-900 dark:text-stone-200 border-b border-stone-200 dark:border-stone-700 overflow-x-auto';
|
|
19
|
-
this.init();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
init() {
|
|
23
|
-
const toolMapping = {
|
|
24
|
-
heading: HeadingTool,
|
|
25
|
-
ul: ULTool,
|
|
26
|
-
ol: OLTool,
|
|
27
|
-
checklist: CheckListTool,
|
|
28
|
-
bold: BoldTool,
|
|
29
|
-
italic: ItalicTool,
|
|
30
|
-
strikethrough: StrikethroughTool,
|
|
31
|
-
blockquote: BlockQuoteTool,
|
|
32
|
-
link: LinkTool
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// Append all tools except preview
|
|
36
|
-
this.options.forEach(tool => {
|
|
37
|
-
if (tool !== 'preview') {
|
|
38
|
-
const ToolClass = toolMapping[tool];
|
|
39
|
-
if (ToolClass) {
|
|
40
|
-
const toolInstance = new ToolClass(this.editor);
|
|
41
|
-
this.toolbar.appendChild(toolInstance.button); // Directly append to toolbar
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// Append preview button at the end
|
|
47
|
-
if (this.options.includes('preview')) {
|
|
48
|
-
const previewToolInstance = new PreviewTool(this.editor);
|
|
49
|
-
this.toolbar.appendChild(previewToolInstance.button); // Directly append to toolbar at the end
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
this.editor.editorContainer.insertBefore(this.toolbar, this.editor.markdownEditorDiv);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export default Toolbar;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class BlockQuoteTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
// Call the parent constructor with the markdown syntax for italic (*)
|
|
6
|
-
super(editor, 'Blockquote');
|
|
7
|
-
this.button = this.createButton(`
|
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M4.58341 17.3211C3.55316 16.2274 3 15 3 13.0103C3 9.51086 5.45651 6.37366 9.03059 4.82318L9.92328 6.20079C6.58804 8.00539 5.93618 10.346 5.67564 11.822C6.21263 11.5443 6.91558 11.4466 7.60471 11.5105C9.40908 11.6778 10.8312 13.159 10.8312 15C10.8312 16.933 9.26416 18.5 7.33116 18.5C6.2581 18.5 5.23196 18.0095 4.58341 17.3211ZM14.5834 17.3211C13.5532 16.2274 13 15 13 13.0103C13 9.51086 15.4565 6.37366 19.0306 4.82318L19.9233 6.20079C16.588 8.00539 15.9362 10.346 15.6756 11.822C16.2126 11.5443 16.9156 11.4466 17.6047 11.5105C19.4091 11.6778 20.8312 13.159 20.8312 15C20.8312 16.933 19.2642 18.5 17.3312 18.5C16.2581 18.5 15.232 18.0095 14.5834 17.3211Z"></path></svg>
|
|
9
|
-
`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
applySyntax() {
|
|
13
|
-
const textarea = this.editor.usertextarea;
|
|
14
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
15
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
16
|
-
|
|
17
|
-
const syntax = '>';
|
|
18
|
-
let newText = '';
|
|
19
|
-
if (selectedText.startsWith(syntax)) {
|
|
20
|
-
// Remove the blockquote syntax if it's already wrapped
|
|
21
|
-
newText = selectedText.slice(syntax.length);
|
|
22
|
-
} else {
|
|
23
|
-
// Apply blockquote syntax
|
|
24
|
-
newText = `${syntax}${selectedText || 'Blockquote text'}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.editor.insertText(newText);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default BlockQuoteTool;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class BoldTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Bold');
|
|
6
|
-
this.button = this.createButton(`
|
|
7
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20">
|
|
8
|
-
<path d="M8 11H12.5C13.8807 11 15 9.88071 15 8.5C15 7.11929 13.8807 6 12.5 6H8V11ZM18 15.5C18 17.9853 15.9853 20 13.5 20H6V4H12.5C14.9853 4 17 6.01472 17 8.5C17 9.70431 16.5269 10.7981 15.7564 11.6058C17.0979 12.3847 18 13.837 18 15.5ZM8 13V18H13.5C14.8807 18 16 16.8807 16 15.5C16 14.1193 14.8807 13 13.5 13H8Z"></path>
|
|
9
|
-
</svg>
|
|
10
|
-
`)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Apply bold syntax (**bold**)
|
|
14
|
-
applySyntax() {
|
|
15
|
-
const textarea = this.editor.usertextarea;
|
|
16
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
17
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
18
|
-
|
|
19
|
-
const syntax = '**';
|
|
20
|
-
let newText = '';
|
|
21
|
-
if (selectedText.startsWith(syntax) && selectedText.endsWith(syntax)) {
|
|
22
|
-
// Remove the bold syntax if it's already wrapped
|
|
23
|
-
newText = selectedText.slice(syntax.length, -syntax.length);
|
|
24
|
-
} else {
|
|
25
|
-
// Apply bold syntax
|
|
26
|
-
newText = `${syntax}${selectedText || 'Bold text'}${syntax}`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
this.editor.insertText(newText);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default BoldTool;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class CheckListTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Check list');
|
|
6
|
-
this.button = this.createButton(`
|
|
7
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M8.00008 6V9H5.00008V6H8.00008ZM3.00008 4V11H10.0001V4H3.00008ZM13.0001 4H21.0001V6H13.0001V4ZM13.0001 11H21.0001V13H13.0001V11ZM13.0001 18H21.0001V20H13.0001V18ZM10.7072 16.2071L9.29297 14.7929L6.00008 18.0858L4.20718 16.2929L2.79297 17.7071L6.00008 20.9142L10.7072 16.2071Z"></path></svg>
|
|
8
|
-
`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
applySyntax() {
|
|
12
|
-
const textarea = this.editor.usertextarea;
|
|
13
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
14
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
15
|
-
|
|
16
|
-
const syntax = '- [x] ';
|
|
17
|
-
let newText = '';
|
|
18
|
-
if (selectedText.startsWith(syntax)) {
|
|
19
|
-
// Remove the checklist syntax if it's already wrapped
|
|
20
|
-
newText = selectedText.slice(syntax.length);
|
|
21
|
-
} else {
|
|
22
|
-
// Apply check list syntax
|
|
23
|
-
newText = `${syntax}${selectedText || 'Check list'}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
this.editor.insertText(newText);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export default CheckListTool;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class HeadingTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Heading');
|
|
6
|
-
this.currentHeading = 1; // Start with Heading 1
|
|
7
|
-
this.button = this.createButton(`
|
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M17 11V4H19V21H17V13H7V21H5V4H7V11H17Z"></path></svg>
|
|
9
|
-
`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Apply heading syntax (e.g., # sample text for h1, ## sample text for h2, etc.)
|
|
13
|
-
applySyntax() {
|
|
14
|
-
const textarea = this.editor.usertextarea;
|
|
15
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
16
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
17
|
-
|
|
18
|
-
// Strip any existing heading symbols (i.e., # or ##) from the selected text
|
|
19
|
-
const headingRegex = /^#+\s*/; // Regex to match any # followed by space
|
|
20
|
-
let cleanText = selectedText.replace(headingRegex, ''); // Remove existing heading
|
|
21
|
-
|
|
22
|
-
let newText = '';
|
|
23
|
-
|
|
24
|
-
// If there is a heading, continue from the current level
|
|
25
|
-
if (selectedText) {
|
|
26
|
-
const currentLevel = selectedText.match(/^#+/); // Match the number of # symbols at the start
|
|
27
|
-
if (currentLevel) {
|
|
28
|
-
let headingCount = currentLevel[0].length;
|
|
29
|
-
if (headingCount === 6) {
|
|
30
|
-
newText = cleanText; // Just plain text
|
|
31
|
-
} else {
|
|
32
|
-
newText = `${'#'.repeat(headingCount + 1)} ${cleanText}`;
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
// If no # symbol, start from # (Heading 1)
|
|
36
|
-
newText = `# ${cleanText}`;
|
|
37
|
-
}
|
|
38
|
-
} else {
|
|
39
|
-
// If no text is selected, use default "Heading"
|
|
40
|
-
newText = `${'#'.repeat(this.currentHeading)} Heading`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Insert the new heading text and replace any selected text
|
|
44
|
-
this.editor.insertText(newText, true);
|
|
45
|
-
|
|
46
|
-
// Cycle heading levels after applying the heading
|
|
47
|
-
if (this.currentHeading === 6) {
|
|
48
|
-
this.currentHeading = 1; // Reset to # for Heading 1 after reaching Heading 6
|
|
49
|
-
} else {
|
|
50
|
-
this.currentHeading++; // Increment the heading level
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default HeadingTool;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class ItalicTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
// Call the parent constructor with the markdown syntax for italic (*)
|
|
6
|
-
super(editor, 'Italic');
|
|
7
|
-
this.button = this.createButton(`
|
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M15 20H7V18H9.92661L12.0425 6H9V4H17V6H14.0734L11.9575 18H15V20Z"></path></svg>
|
|
9
|
-
`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
applySyntax() {
|
|
13
|
-
const textarea = this.editor.usertextarea;
|
|
14
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
15
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
16
|
-
|
|
17
|
-
const syntax = '*';
|
|
18
|
-
let newText = '';
|
|
19
|
-
if (selectedText.startsWith(syntax) && selectedText.endsWith(syntax)) {
|
|
20
|
-
// Remove the italic syntax if it's already wrapped
|
|
21
|
-
newText = selectedText.slice(syntax.length, -syntax.length);
|
|
22
|
-
} else {
|
|
23
|
-
// Apply italic syntax
|
|
24
|
-
newText = `${syntax}${selectedText || 'Italic text'}${syntax}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.editor.insertText(newText);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default ItalicTool;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class LinkTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Link');
|
|
6
|
-
this.button = this.createButton(`
|
|
7
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20">
|
|
8
|
-
<path d="M18.3638 15.5355L16.9496 14.1213L18.3638 12.7071C20.3164 10.7545 20.3164 7.58866 18.3638 5.63604C16.4112 3.68341 13.2453 3.68341 11.2927 5.63604L9.87849 7.05025L8.46428 5.63604L9.87849 4.22182C12.6122 1.48815 17.0443 1.48815 19.778 4.22182C22.5117 6.95549 22.5117 11.3876 19.778 14.1213L18.3638 15.5355ZM15.5353 18.364L14.1211 19.7782C11.3875 22.5118 6.95531 22.5118 4.22164 19.7782C1.48797 17.0445 1.48797 12.6123 4.22164 9.87868L5.63585 8.46446L7.05007 9.87868L5.63585 11.2929C3.68323 13.2455 3.68323 16.4113 5.63585 18.364C7.58847 20.3166 10.7543 20.3166 12.7069 18.364L14.1211 16.9497L15.5353 18.364ZM14.8282 7.75736L16.2425 9.17157L9.17139 16.2426L7.75717 14.8284L14.8282 7.75736Z"></path>
|
|
9
|
-
</svg>
|
|
10
|
-
`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Apply link syntax [text](url)
|
|
14
|
-
applySyntax() {
|
|
15
|
-
const textarea = this.editor.usertextarea;
|
|
16
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
17
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
18
|
-
|
|
19
|
-
// Check if the selected text contains a link syntax [text](url)
|
|
20
|
-
const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/;
|
|
21
|
-
|
|
22
|
-
if (selectedText && linkRegex.test(selectedText)) {
|
|
23
|
-
// If the selected text is already a link, extract the text inside the brackets
|
|
24
|
-
const match = selectedText.match(linkRegex);
|
|
25
|
-
const linkText = match[1]; // Text inside the square brackets
|
|
26
|
-
|
|
27
|
-
// Replace the selected text with just the text
|
|
28
|
-
textarea.setRangeText(linkText, selectionStart, selectionEnd, 'select');
|
|
29
|
-
} else {
|
|
30
|
-
// If no link syntax, prompt for the URL and apply the syntax
|
|
31
|
-
const url = prompt("Enter the URL:", "https://");
|
|
32
|
-
if (url) {
|
|
33
|
-
let newText = '';
|
|
34
|
-
if (selectedText) {
|
|
35
|
-
newText = `[${selectedText}](${url})`; // Insert the link with selected text
|
|
36
|
-
} else {
|
|
37
|
-
newText = `[Link text](${url})`; // Insert a placeholder text if nothing is selected
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.editor.insertText(newText); // Insert the constructed link markdown
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export default LinkTool;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class OLTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Ordered list');
|
|
6
|
-
this.button = this.createButton(`
|
|
7
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M8 4H21V6H8V4ZM5 3V6H6V7H3V6H4V4H3V3H5ZM3 14V11.5H5V11H3V10H6V12.5H4V13H6V14H3ZM5 19.5H3V18.5H5V18H3V17H6V21H3V20H5V19.5ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z"></path></svg>
|
|
8
|
-
`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
applySyntax() {
|
|
12
|
-
const textarea = this.editor.usertextarea;
|
|
13
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
14
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
15
|
-
|
|
16
|
-
const syntax = '1. ';
|
|
17
|
-
let newText = '';
|
|
18
|
-
if (selectedText.startsWith(syntax)) {
|
|
19
|
-
// Remove the ordered syntax if it's already wrapped
|
|
20
|
-
newText = selectedText.slice(syntax.length);
|
|
21
|
-
} else {
|
|
22
|
-
// Apply ordered list syntax
|
|
23
|
-
newText = `${syntax}${selectedText || 'Ordered list'}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
this.editor.insertText(newText);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export default OLTool;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
// #components/Toolbar/tools/PreviewToggleTool.js
|
|
2
|
-
import MakeTool from '../MakeTool.js';
|
|
3
|
-
|
|
4
|
-
class PreviewTool extends MakeTool {
|
|
5
|
-
constructor(editor) {
|
|
6
|
-
// No markdown syntax for preview toggle, so we call the parent constructor with empty values
|
|
7
|
-
super(editor, 'Preview');
|
|
8
|
-
this.button = this.createButton(`
|
|
9
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M11 5H5V19H11V5ZM13 5V19H19V5H13ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3Z"></path></svg>
|
|
10
|
-
`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Override applySyntax to handle preview toggling
|
|
14
|
-
applySyntax() {
|
|
15
|
-
const previewWrapper = this.editor.previewContent?.parentNode;
|
|
16
|
-
const editorDiv = this.editor.markdownEditorDiv;
|
|
17
|
-
|
|
18
|
-
if (!previewWrapper || !editorDiv) return;
|
|
19
|
-
|
|
20
|
-
// Toggle the preview's visibility by switching between 'block' and 'hidden' classes
|
|
21
|
-
if (this.editor.preview) {
|
|
22
|
-
this.enablePreview(previewWrapper, editorDiv);
|
|
23
|
-
} else {
|
|
24
|
-
this.disablePreview(previewWrapper, editorDiv);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Method to hide the preview (disable it)
|
|
29
|
-
disablePreview(previewWrapper, editorDiv) {
|
|
30
|
-
|
|
31
|
-
this.editor.preview = true;
|
|
32
|
-
|
|
33
|
-
editorDiv.parentNode.classList.toggle('fixed');
|
|
34
|
-
editorDiv.parentNode.classList.toggle('top-0');
|
|
35
|
-
editorDiv.parentNode.classList.toggle('inset-x-0');
|
|
36
|
-
editorDiv.parentNode.classList.toggle('rounded-md');
|
|
37
|
-
editorDiv.parentNode.classList.toggle('z-999');
|
|
38
|
-
|
|
39
|
-
previewWrapper.classList.toggle('hidden');
|
|
40
|
-
|
|
41
|
-
// Add grid layout and divide classes to the editor div
|
|
42
|
-
editorDiv.classList.remove(
|
|
43
|
-
'md:grid',
|
|
44
|
-
'md:grid-cols-2',
|
|
45
|
-
'md:divide-x',
|
|
46
|
-
'md:rtl:divide-x-reverse',
|
|
47
|
-
'md:divide-stone-300',
|
|
48
|
-
'dark:md:divide-stone-700'
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
editorDiv.querySelector(".textarea-wrapper").classList.remove(
|
|
52
|
-
'h-[90lvh]',
|
|
53
|
-
'hidden',
|
|
54
|
-
'md:block'
|
|
55
|
-
);
|
|
56
|
-
this.editor.render(); // Re-render content in the preview
|
|
57
|
-
|
|
58
|
-
editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.remove("h-[90lvh]!");
|
|
59
|
-
|
|
60
|
-
document.querySelector("body").classList.remove('overflow-hidden');
|
|
61
|
-
|
|
62
|
-
document.querySelectorAll('.markdown-btn').forEach(button => {
|
|
63
|
-
if (!button.classList.contains('preview-btn')) {
|
|
64
|
-
button.classList.remove('pointer-events-none', 'md:pointer-events-auto', 'opacity-25', 'md:opacity-100');
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Method to show the preview (enable it)
|
|
70
|
-
enablePreview(previewWrapper, editorDiv) {
|
|
71
|
-
|
|
72
|
-
this.editor.preview = false;
|
|
73
|
-
|
|
74
|
-
editorDiv.parentNode.classList.toggle('fixed');
|
|
75
|
-
editorDiv.parentNode.classList.toggle('top-0');
|
|
76
|
-
editorDiv.parentNode.classList.toggle('inset-x-0');
|
|
77
|
-
editorDiv.parentNode.classList.toggle('rounded-md');
|
|
78
|
-
editorDiv.parentNode.classList.toggle('z-999');
|
|
79
|
-
|
|
80
|
-
previewWrapper.classList.toggle('hidden');
|
|
81
|
-
// Remove grid layout and divide classes from the editor div
|
|
82
|
-
editorDiv.classList.add(
|
|
83
|
-
'md:grid',
|
|
84
|
-
'md:grid-cols-2',
|
|
85
|
-
'md:divide-x',
|
|
86
|
-
'md:rtl:divide-x-reverse',
|
|
87
|
-
'md:divide-stone-300',
|
|
88
|
-
'dark:md:divide-stone-700'
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
editorDiv.querySelector(".textarea-wrapper").classList.add(
|
|
92
|
-
'h-[90lvh]',
|
|
93
|
-
'hidden',
|
|
94
|
-
'md:block'
|
|
95
|
-
);
|
|
96
|
-
editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.add("h-[90lvh]!");
|
|
97
|
-
|
|
98
|
-
document.querySelector("body").classList.add('overflow-hidden');
|
|
99
|
-
|
|
100
|
-
document.querySelectorAll('.markdown-btn').forEach(button => {
|
|
101
|
-
if (!button.classList.contains('preview-btn')) {
|
|
102
|
-
button.classList.add('pointer-events-none', 'md:pointer-events-auto', 'opacity-25', 'md:opacity-100');
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default PreviewTool;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class StrikethroughTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
// Call the parent constructor with the markdown syntax for strikethrough (~~)
|
|
6
|
-
super(editor, 'Strikethrough');
|
|
7
|
-
this.button = this.createButton(`
|
|
8
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M17.1538 14C17.3846 14.5161 17.5 15.0893 17.5 15.7196C17.5 17.0625 16.9762 18.1116 15.9286 18.867C14.8809 19.6223 13.4335 20 11.5862 20C9.94674 20 8.32335 19.6185 6.71592 18.8555V16.6009C8.23538 17.4783 9.7908 17.917 11.3822 17.917C13.9333 17.917 15.2128 17.1846 15.2208 15.7196C15.2208 15.0939 15.0049 14.5598 14.5731 14.1173C14.5339 14.0772 14.4939 14.0381 14.4531 14H3V12H21V14H17.1538ZM13.076 11H7.62908C7.4566 10.8433 7.29616 10.6692 7.14776 10.4778C6.71592 9.92084 6.5 9.24559 6.5 8.45207C6.5 7.21602 6.96583 6.165 7.89749 5.299C8.82916 4.43299 10.2706 4 12.2219 4C13.6934 4 15.1009 4.32808 16.4444 4.98426V7.13591C15.2448 6.44921 13.9293 6.10587 12.4978 6.10587C10.0187 6.10587 8.77917 6.88793 8.77917 8.45207C8.77917 8.87172 8.99709 9.23796 9.43293 9.55079C9.86878 9.86362 10.4066 10.1135 11.0463 10.3004C11.6665 10.4816 12.3431 10.7148 13.076 11H13.076Z"></path></svg>
|
|
9
|
-
`);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
applySyntax() {
|
|
13
|
-
const textarea = this.editor.usertextarea;
|
|
14
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
15
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
16
|
-
|
|
17
|
-
const syntax = '~';
|
|
18
|
-
let newText = '';
|
|
19
|
-
if (selectedText.startsWith(syntax) && selectedText.endsWith(syntax)) {
|
|
20
|
-
// Remove the strikethrough syntax if it's already wrapped
|
|
21
|
-
newText = selectedText.slice(syntax.length, -syntax.length);
|
|
22
|
-
} else {
|
|
23
|
-
// Apply strikethrough syntax
|
|
24
|
-
newText = `${syntax}${selectedText || 'Strikethrough text'}${syntax}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
this.editor.insertText(newText);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default StrikethroughTool;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import MakeTool from '../MakeTool.js';
|
|
2
|
-
|
|
3
|
-
class ULTool extends MakeTool {
|
|
4
|
-
constructor(editor) {
|
|
5
|
-
super(editor, 'Unordered list');
|
|
6
|
-
this.button = this.createButton(`
|
|
7
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M8 4H21V6H8V4ZM4.5 6.5C3.67157 6.5 3 5.82843 3 5C3 4.17157 3.67157 3.5 4.5 3.5C5.32843 3.5 6 4.17157 6 5C6 5.82843 5.32843 6.5 4.5 6.5ZM4.5 13.5C3.67157 13.5 3 12.8284 3 12C3 11.1716 3.67157 10.5 4.5 10.5C5.32843 10.5 6 11.1716 6 12C6 12.8284 5.32843 13.5 4.5 13.5ZM4.5 20.4C3.67157 20.4 3 19.7284 3 18.9C3 18.0716 3.67157 17.4 4.5 17.4C5.32843 17.4 6 18.0716 6 18.9C6 19.7284 5.32843 20.4 4.5 20.4ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z"></path></svg>
|
|
8
|
-
`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
applySyntax() {
|
|
12
|
-
const textarea = this.editor.usertextarea;
|
|
13
|
-
const { selectionStart, selectionEnd } = textarea;
|
|
14
|
-
const selectedText = textarea.value.substring(selectionStart, selectionEnd);
|
|
15
|
-
|
|
16
|
-
const syntax = '- ';
|
|
17
|
-
let newText = '';
|
|
18
|
-
if (selectedText.startsWith(syntax)) {
|
|
19
|
-
// Remove the Unordered syntax if it's already wrapped
|
|
20
|
-
newText = selectedText.slice(syntax.length);
|
|
21
|
-
} else {
|
|
22
|
-
// Apply Unordered list syntax
|
|
23
|
-
newText = `${syntax}${selectedText || 'Unordered list'}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
this.editor.insertText(newText);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export default ULTool;
|