cm-md-editor 2.3.2 → 2.4.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Stefan Haack (shaack.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,15 +1,83 @@
1
1
  # cm-md-editor
2
2
 
3
- This is a minimal **markdown editor** which is used in chessmail.de.
3
+ A minimal, dependency-free markdown editor as a vanilla JavaScript ES6 module.
4
+
5
+ [Demo](https://shaack.com/projekte/cm-md-editor/)
6
+
7
+ ![Screenshot](screenshot.png)
4
8
 
5
9
  ## Key features
6
10
 
7
- - Vanilla JavaScript module, without dependencies
8
- - Supports outlines with tab and shift-tab to indent and outdent
9
- - Supports the **bold** syntax with command-b/ctrl-b
10
- - Supports the _italic_ syntax with command-i/ctrl-i
11
- - Supports undo and redo with command-z/ctrl-z and command-shift-z/ctrl-shift-z
12
- - It is…
13
- - lightweight
14
- - easy to use
15
- - fast
11
+ - Vanilla JavaScript module, zero dependencies
12
+ - Syntax highlighting for headings, bold, italic, code, lists, links, images, blockquotes, HTML tags, horizontal rules, front matter and more
13
+ - Toolbar with configurable buttons (headings, bold, italic, lists, links, images)
14
+ - Word wrap toggle with persistent state (localStorage)
15
+ - List mode: Tab/Shift-Tab to indent/outdent, auto-continuation on Enter
16
+ - Bold with Ctrl/Cmd+B, italic with Ctrl/Cmd+I
17
+ - Native undo/redo support (Ctrl/Cmd+Z / Ctrl/Cmd+Shift+Z)
18
+ - Lightweight, fast, easy to use
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install cm-md-editor
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ ```html
29
+ <textarea id="editor"></textarea>
30
+
31
+ <script type="module">
32
+ import {MdEditor} from "cm-md-editor/src/MdEditor.js"
33
+
34
+ const editor = new MdEditor(document.getElementById("editor"))
35
+ </script>
36
+ ```
37
+
38
+ With custom configuration:
39
+
40
+ ```javascript
41
+ const editor = new MdEditor(document.getElementById("editor"), {
42
+ wordWrap: false,
43
+ toolbarButtons: ["h1", "h2", "bold", "italic", "ul", "link"]
44
+ })
45
+ ```
46
+
47
+ ## Configuration (props)
48
+
49
+ All props are optional. Pass them as the second argument to the constructor.
50
+
51
+ | Prop | Type | Default | Description |
52
+ |------|------|---------|-------------|
53
+ | `wordWrap` | `boolean` | `true` | Default word wrap state. Overridden by localStorage if the user has toggled it |
54
+ | `toolbarButtons` | `string[]` | `["h1", "h2", "h3", "bold", "italic", "ul", "ol", "link", "image"]` | Which toolbar buttons to show. Available: `h1`, `h2`, `h3`, `bold`, `italic`, `ul`, `ol`, `link`, `image` |
55
+ | `colorHeading` | `string` | `"100,160,255"` | RGB color for headings |
56
+ | `colorCode` | `string` | `"130,170,200"` | RGB color for code spans and fenced code blocks |
57
+ | `colorComment` | `string` | `"128,128,128"` | RGB color for HTML comments |
58
+ | `colorLink` | `string` | `"100,180,220"` | RGB color for links and images |
59
+ | `colorBlockquote` | `string` | `"100,200,150"` | RGB color for blockquote prefixes |
60
+ | `colorList` | `string` | `"100,200,150"` | RGB color for list markers |
61
+ | `colorStrikethrough` | `string` | `"255,100,100"` | RGB color for ~~strikethrough~~ |
62
+ | `colorBold` | `string` | `"255,180,80"` | RGB color for **bold** |
63
+ | `colorItalic` | `string` | `"180,130,255"` | RGB color for _italic_ |
64
+ | `colorHtmlTag` | `string` | `"200,120,120"` | RGB color for HTML tags |
65
+ | `colorHorizontalRule` | `string` | `"128,128,200"` | RGB color for horizontal rules |
66
+ | `colorEscape` | `string` | `"128,128,128"` | RGB color for escape sequences |
67
+ | `colorFrontMatter` | `string` | `"128,128,200"` | RGB color for YAML front matter |
68
+
69
+ Colors are specified as RGB strings (e.g. `"255,180,80"`) and rendered at full opacity.
70
+
71
+ ## Keyboard shortcuts
72
+
73
+ | Shortcut | Action |
74
+ |----------|--------|
75
+ | Ctrl/Cmd + B | Toggle bold |
76
+ | Ctrl/Cmd + I | Toggle italic |
77
+ | Tab | Indent list item or insert tab |
78
+ | Shift + Tab | Outdent list item |
79
+ | Enter | Auto-continue list (unordered and ordered) |
80
+
81
+ ## License
82
+
83
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cm-md-editor",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "a simple markdown editor",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/screenshot.png ADDED
Binary file
package/src/MdEditor.js CHANGED
@@ -7,7 +7,6 @@ export class MdEditor {
7
7
  constructor(element, props) {
8
8
  this.element = element
9
9
  this.props = {
10
- syntaxHighlight: 1, // opacity of the highlighting, set 0 to disable
11
10
  colorHeading: "100,160,255",
12
11
  colorCode: "130,170,200",
13
12
  colorComment: "128,128,128",
@@ -21,12 +20,17 @@ export class MdEditor {
21
20
  colorHorizontalRule: "128,128,200",
22
21
  colorEscape: "128,128,128",
23
22
  colorFrontMatter: "128,128,200",
23
+ wordWrap: true,
24
24
  toolbarButtons: ["h1", "h2", "h3", "bold", "italic", "ul", "ol", "link", "image"],
25
25
  ...props
26
26
  }
27
27
  this.element.addEventListener('keydown', (e) => this.handleKeyDown(e))
28
28
  this.createToolbar()
29
29
  this.createHighlightBackdrop()
30
+ if (!this.wrapEnabled && this.highlightLayer) {
31
+ this.highlightLayer.style.whiteSpace = 'pre'
32
+ this.highlightLayer.style.overflowWrap = 'normal'
33
+ }
30
34
  }
31
35
 
32
36
  createToolbar() {
@@ -73,7 +77,9 @@ export class MdEditor {
73
77
  toolbar.appendChild(spacer)
74
78
 
75
79
  // Wrap toggle button
76
- this.wrapEnabled = true
80
+ this.wrapStorageKey = 'mdEditor_wrap_' + (this.element.id || this.element.name || 'default')
81
+ const savedWrap = localStorage.getItem(this.wrapStorageKey)
82
+ this.wrapEnabled = savedWrap !== null ? savedWrap === 'true' : this.props.wordWrap
77
83
  this.wrapButton = document.createElement('button')
78
84
  this.wrapButton.type = 'button'
79
85
  this.wrapButton.title = 'Toggle word wrap'
@@ -86,12 +92,16 @@ export class MdEditor {
86
92
  e.preventDefault()
87
93
  this.toggleWrapMode()
88
94
  })
89
- this.wrapButton.style.opacity = '0.9'
95
+ this.wrapButton.style.opacity = this.wrapEnabled ? '0.9' : '0.4'
90
96
  toolbar.appendChild(this.wrapButton)
97
+ // Apply saved wrap state
98
+ if (!this.wrapEnabled) {
99
+ this.element.style.whiteSpace = 'pre'
100
+ this.element.style.overflowX = 'auto'
101
+ }
91
102
  }
92
103
 
93
104
  createHighlightBackdrop() {
94
- if (!this.props.syntaxHighlight) return
95
105
  const container = this.element.parentNode
96
106
  container.style.position = 'relative'
97
107
  this.backdrop = document.createElement('div')
@@ -101,7 +111,7 @@ export class MdEditor {
101
111
 
102
112
  // Copy textarea computed styles to backdrop
103
113
  const cs = window.getComputedStyle(this.element)
104
- this.backdrop.style.cssText = `position:absolute;overflow:hidden;pointer-events:none;z-index:1;opacity:${this.props.syntaxHighlight};`
114
+ this.backdrop.style.cssText = `position:absolute;overflow:hidden;pointer-events:none;z-index:1;`
105
115
  this.highlightLayer.style.cssText = `white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;`
106
116
 
107
117
  const syncStyles = () => {
@@ -333,6 +343,7 @@ export class MdEditor {
333
343
 
334
344
  toggleWrapMode() {
335
345
  this.wrapEnabled = !this.wrapEnabled
346
+ localStorage.setItem(this.wrapStorageKey, this.wrapEnabled)
336
347
  const wrap = this.wrapEnabled
337
348
  this.element.style.whiteSpace = wrap ? 'pre-wrap' : 'pre'
338
349
  this.element.style.overflowX = wrap ? 'hidden' : 'auto'