prosemirror-menu 1.3.0 → 1.3.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/CHANGELOG.md +12 -0
- package/CONTRIBUTING.md +22 -18
- package/README.md +4 -4
- package/dist/index.cjs +7 -2
- package/dist/index.js +5 -3
- package/package.json +2 -2
- package/src/README.md +4 -4
- package/src/icons.ts +1 -0
- package/src/menu.ts +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 1.3.2 (2026-04-17)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Give menu buttons a `type=button` attribute to make sure they don't try to submit surrounding forms.
|
|
6
|
+
|
|
7
|
+
## 1.3.1 (2026-04-15)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Move focus to button before closing a submenu, to avoid focus moving back to the document root.
|
|
12
|
+
|
|
1
13
|
## 1.3.0 (2026-02-17)
|
|
2
14
|
|
|
3
15
|
### New features
|
package/CONTRIBUTING.md
CHANGED
|
@@ -12,7 +12,7 @@ Community discussion, questions, and informal bug reporting is done on the
|
|
|
12
12
|
## Submitting bug reports
|
|
13
13
|
|
|
14
14
|
Report bugs on the
|
|
15
|
-
[
|
|
15
|
+
[issue tracker](https://code.haverbeke.berlin/prosemirror/prosemirror/issues).
|
|
16
16
|
Before reporting a bug, please read these pointers.
|
|
17
17
|
|
|
18
18
|
- The issue tracker is for *bugs*, not requests for help. Questions
|
|
@@ -34,21 +34,28 @@ Before reporting a bug, please read these pointers.
|
|
|
34
34
|
|
|
35
35
|
## Contributing code
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Code generated by a language model is not welcome in this project.
|
|
38
|
+
Please don't waste my time with it.
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
If you want to make a change that involves a significant overhaul of
|
|
41
|
+
the code or introduces a user-visible new feature, create an
|
|
42
|
+
[issue](https://code.haverbeke.berlin/prosemirror/prosemirror/issues/)
|
|
43
|
+
first with your proposal.
|
|
44
|
+
|
|
45
|
+
- Make sure you have a [Codeberg](https://codeberg.org/user/sign_up)
|
|
46
|
+
or [GitHub](https://github.com/signup/free) account.
|
|
47
|
+
|
|
48
|
+
- Use that to create a [code.haverbeke.berlin
|
|
49
|
+
account](https://code.haverbeke.berlin/user/login).
|
|
50
|
+
|
|
51
|
+
- Fork the relevant repository.
|
|
41
52
|
|
|
42
53
|
- Create a local checkout of the code. You can use the
|
|
43
|
-
[main repository](https://
|
|
54
|
+
[main repository](https://code.haverbeke.berlin/prosemirror/prosemirror) to
|
|
44
55
|
easily check out all core modules.
|
|
45
56
|
|
|
46
57
|
- Make your changes, and commit them
|
|
47
58
|
|
|
48
|
-
- Follow the code style of the rest of the project (see below). Run
|
|
49
|
-
`npm run lint` (in the main repository checkout) to make sure that
|
|
50
|
-
the linter is happy.
|
|
51
|
-
|
|
52
59
|
- If your changes are easy to test or likely to regress, add tests in
|
|
53
60
|
the relevant `test/` directory. Either put them in an existing
|
|
54
61
|
`test-*.js` file, if they fit there, or add a new file.
|
|
@@ -56,13 +63,13 @@ Before reporting a bug, please read these pointers.
|
|
|
56
63
|
- Make sure all tests pass. Run `npm run test` to verify tests pass
|
|
57
64
|
(you will need Node.js v6+).
|
|
58
65
|
|
|
59
|
-
- Submit a pull request
|
|
60
|
-
|
|
66
|
+
- Submit a pull request. Don't put more than one feature/fix in a
|
|
67
|
+
single pull request.
|
|
61
68
|
|
|
62
69
|
By contributing code to ProseMirror you
|
|
63
70
|
|
|
64
71
|
- Agree to license the contributed code under the project's [MIT
|
|
65
|
-
license](https://
|
|
72
|
+
license](https://code.haverbeke.berlin/prosemirror/prosemirror/blob/main/LICENSE).
|
|
66
73
|
|
|
67
74
|
- Confirm that you have the right to contribute and license the code
|
|
68
75
|
in question. (Either you hold all rights on the code, or the rights
|
|
@@ -82,19 +89,16 @@ By contributing code to ProseMirror you
|
|
|
82
89
|
- Follow the surrounding code when it comes to spacing, brace
|
|
83
90
|
placement, etc.
|
|
84
91
|
|
|
85
|
-
- Brace-less single-statement bodies are encouraged
|
|
86
|
-
don't impact readability
|
|
92
|
+
- Brace-less single-statement bodies are encouraged whenever they
|
|
93
|
+
don't impact readability.
|
|
87
94
|
|
|
88
|
-
- [getdocs](https://
|
|
95
|
+
- [getdocs-ts](https://code.haverbeke.berlin/marijn/getdocs-ts)-style doc comments
|
|
89
96
|
above items that are part of the public API.
|
|
90
97
|
|
|
91
98
|
- When documenting non-public items, you can put the type after a
|
|
92
99
|
single colon, so that getdocs doesn't pick it up and add it to the
|
|
93
100
|
API reference.
|
|
94
101
|
|
|
95
|
-
- The linter (`npm run lint`) complains about unused variables and
|
|
96
|
-
functions. Prefix their names with an underscore to muffle it.
|
|
97
|
-
|
|
98
102
|
- ProseMirror does *not* follow JSHint or JSLint prescribed style.
|
|
99
103
|
Patches that try to 'fix' code to pass one of these linters will not
|
|
100
104
|
be accepted.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# prosemirror-menu
|
|
2
2
|
|
|
3
|
-
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://
|
|
3
|
+
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) ]
|
|
4
4
|
|
|
5
5
|
This is a non-core example module for [ProseMirror](https://prosemirror.net).
|
|
6
6
|
ProseMirror is a well-behaved rich semantic content editor based on
|
|
@@ -19,10 +19,10 @@ ProseMirror, publish your fork, and if it works for me, I'll gladly
|
|
|
19
19
|
deprecate this in favor of your module.
|
|
20
20
|
|
|
21
21
|
This code is released under an
|
|
22
|
-
[MIT license](https://
|
|
22
|
+
[MIT license](https://code.haverbeke.berlin/prosemirror/prosemirror/src/branch/main/LICENSE).
|
|
23
23
|
There's a [forum](http://discuss.prosemirror.net) for general
|
|
24
24
|
discussion and support requests, and the
|
|
25
|
-
[
|
|
25
|
+
[bug tracker](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/issues)
|
|
26
26
|
is the place to report issues.
|
|
27
27
|
|
|
28
28
|
## Documentation
|
|
@@ -31,7 +31,7 @@ This module defines a number of building blocks for ProseMirror menus,
|
|
|
31
31
|
along with a [menu bar](#menu.menuBar) implementation.
|
|
32
32
|
|
|
33
33
|
When using this module, you should make sure its
|
|
34
|
-
[`style/menu.css`](https://
|
|
34
|
+
[`style/menu.css`](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/src/branch/main/style/menu.css)
|
|
35
35
|
file is loaded into your page.
|
|
36
36
|
|
|
37
37
|
### interface MenuElement
|
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,7 @@ function getIcon(root, icon) {
|
|
|
28
28
|
var doc = (root.nodeType == 9 ? root : root.ownerDocument) || document;
|
|
29
29
|
var node = doc.createElement("button");
|
|
30
30
|
node.className = prefix$2;
|
|
31
|
+
node.type = "button";
|
|
31
32
|
if (icon.path) {
|
|
32
33
|
var path = icon.path,
|
|
33
34
|
width = icon.width,
|
|
@@ -77,7 +78,9 @@ var MenuItem = function () {
|
|
|
77
78
|
key: "render",
|
|
78
79
|
value: function render(view) {
|
|
79
80
|
var spec = this.spec;
|
|
80
|
-
var dom = spec.render ? spec.render(view) : spec.icon ? getIcon(view.root, spec.icon) : spec.label ? crel("button",
|
|
81
|
+
var dom = spec.render ? spec.render(view) : spec.icon ? getIcon(view.root, spec.icon) : spec.label ? crel("button", {
|
|
82
|
+
type: "button"
|
|
83
|
+
}, translate(view, spec.label)) : null;
|
|
81
84
|
if (!dom) throw new RangeError("MenuItem without icon or label property");
|
|
82
85
|
if (spec.title) {
|
|
83
86
|
var title = typeof spec.title === "function" ? spec.title(view.state) : spec.title;
|
|
@@ -155,6 +158,7 @@ var Dropdown = function () {
|
|
|
155
158
|
this.focusables = content.focusables;
|
|
156
159
|
var win = view.dom.ownerDocument.defaultView || window;
|
|
157
160
|
var btn = crel("button", {
|
|
161
|
+
type: "button",
|
|
158
162
|
"class": prefix$1 + "-dropdown " + (this.options["class"] || ""),
|
|
159
163
|
style: this.options.css,
|
|
160
164
|
"aria-haspopup": "menu",
|
|
@@ -190,8 +194,8 @@ var Dropdown = function () {
|
|
|
190
194
|
if (keyboardMoveFocus(_this, event, "vertical")) ;else if (event.key === "Escape") {
|
|
191
195
|
event.preventDefault();
|
|
192
196
|
event.stopPropagation();
|
|
193
|
-
close();
|
|
194
197
|
btn.focus();
|
|
198
|
+
close();
|
|
195
199
|
}
|
|
196
200
|
});
|
|
197
201
|
open.node.addEventListener("focusout", function () {
|
|
@@ -336,6 +340,7 @@ var DropdownSubmenu = function () {
|
|
|
336
340
|
this.focusables = items.focusables;
|
|
337
341
|
var win = view.dom.ownerDocument.defaultView || window;
|
|
338
342
|
var btn = crel("button", {
|
|
343
|
+
type: "button",
|
|
339
344
|
"class": prefix$1 + "-submenu-label"
|
|
340
345
|
}, translate(view, this.options.label || ""));
|
|
341
346
|
var wrap = crel("div", {
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ function getIcon(root, icon) {
|
|
|
16
16
|
let doc = (root.nodeType == 9 ? root : root.ownerDocument) || document;
|
|
17
17
|
let node = doc.createElement("button");
|
|
18
18
|
node.className = prefix$2;
|
|
19
|
+
node.type = "button";
|
|
19
20
|
if (icon.path) {
|
|
20
21
|
let { path, width, height } = icon;
|
|
21
22
|
let name = "pm-icon-" + hashPath(path).toString(16);
|
|
@@ -78,7 +79,7 @@ class MenuItem {
|
|
|
78
79
|
let spec = this.spec;
|
|
79
80
|
let dom = spec.render ? spec.render(view)
|
|
80
81
|
: spec.icon ? getIcon(view.root, spec.icon)
|
|
81
|
-
: spec.label ? crel("button",
|
|
82
|
+
: spec.label ? crel("button", { type: "button" }, translate(view, spec.label))
|
|
82
83
|
: null;
|
|
83
84
|
if (!dom)
|
|
84
85
|
throw new RangeError("MenuItem without icon or label property");
|
|
@@ -169,6 +170,7 @@ class Dropdown {
|
|
|
169
170
|
this.focusables = content.focusables;
|
|
170
171
|
let win = view.dom.ownerDocument.defaultView || window;
|
|
171
172
|
let btn = crel("button", {
|
|
173
|
+
type: "button",
|
|
172
174
|
class: prefix$1 + "-dropdown " + (this.options.class || ""),
|
|
173
175
|
style: this.options.css,
|
|
174
176
|
"aria-haspopup": "menu",
|
|
@@ -208,8 +210,8 @@ class Dropdown {
|
|
|
208
210
|
else if (event.key === "Escape") {
|
|
209
211
|
event.preventDefault();
|
|
210
212
|
event.stopPropagation();
|
|
211
|
-
close();
|
|
212
213
|
btn.focus();
|
|
214
|
+
close();
|
|
213
215
|
}
|
|
214
216
|
});
|
|
215
217
|
open.node.addEventListener("focusout", () => {
|
|
@@ -354,7 +356,7 @@ class DropdownSubmenu {
|
|
|
354
356
|
let items = renderDropdownItems(this.content, view);
|
|
355
357
|
this.focusables = items.focusables;
|
|
356
358
|
let win = view.dom.ownerDocument.defaultView || window;
|
|
357
|
-
let btn = crel("button", { class: prefix$1 + "-submenu-label" }, translate(view, this.options.label || ""));
|
|
359
|
+
let btn = crel("button", { type: "button", class: prefix$1 + "-submenu-label" }, translate(view, this.options.label || ""));
|
|
358
360
|
let wrap = crel("div", { class: prefix$1 + "-submenu-wrap" }, btn, crel("div", { class: prefix$1 + "-submenu" }, items.dom));
|
|
359
361
|
let listeningOnClose = null;
|
|
360
362
|
let openSubmenu = (e) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prosemirror-menu",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Simple menu elements for ProseMirror",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
|
-
"url": "git://
|
|
28
|
+
"url": "git+https://code.haverbeke.berlin/prosemirror/prosemirror-menu.git"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"crelt": "^1.0.0",
|
package/src/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# prosemirror-menu
|
|
2
2
|
|
|
3
|
-
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://
|
|
3
|
+
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) ]
|
|
4
4
|
|
|
5
5
|
This is a non-core example module for [ProseMirror](https://prosemirror.net).
|
|
6
6
|
ProseMirror is a well-behaved rich semantic content editor based on
|
|
@@ -19,10 +19,10 @@ ProseMirror, publish your fork, and if it works for me, I'll gladly
|
|
|
19
19
|
deprecate this in favor of your module.
|
|
20
20
|
|
|
21
21
|
This code is released under an
|
|
22
|
-
[MIT license](https://
|
|
22
|
+
[MIT license](https://code.haverbeke.berlin/prosemirror/prosemirror/src/branch/main/LICENSE).
|
|
23
23
|
There's a [forum](http://discuss.prosemirror.net) for general
|
|
24
24
|
discussion and support requests, and the
|
|
25
|
-
[
|
|
25
|
+
[bug tracker](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/issues)
|
|
26
26
|
is the place to report issues.
|
|
27
27
|
|
|
28
28
|
## Documentation
|
|
@@ -31,7 +31,7 @@ This module defines a number of building blocks for ProseMirror menus,
|
|
|
31
31
|
along with a [menu bar](#menu.menuBar) implementation.
|
|
32
32
|
|
|
33
33
|
When using this module, you should make sure its
|
|
34
|
-
[`style/menu.css`](https://
|
|
34
|
+
[`style/menu.css`](https://code.haverbeke.berlin/prosemirror/prosemirror-menu/src/branch/main/style/menu.css)
|
|
35
35
|
file is loaded into your page.
|
|
36
36
|
|
|
37
37
|
@MenuElement
|
package/src/icons.ts
CHANGED
|
@@ -17,6 +17,7 @@ export function getIcon(
|
|
|
17
17
|
let doc = (root.nodeType == 9 ? root as Document : root.ownerDocument) || document
|
|
18
18
|
let node = doc.createElement("button")
|
|
19
19
|
node.className = prefix
|
|
20
|
+
node.type = "button"
|
|
20
21
|
if ((icon as any).path) {
|
|
21
22
|
let {path, width, height} = icon as {path: string, width: number, height: number}
|
|
22
23
|
let name = "pm-icon-" + hashPath(path).toString(16)
|
package/src/menu.ts
CHANGED
|
@@ -37,7 +37,7 @@ export class MenuItem<E extends HTMLElement = HTMLButtonElement> implements Menu
|
|
|
37
37
|
let spec = this.spec
|
|
38
38
|
let dom = spec.render ? spec.render(view)
|
|
39
39
|
: spec.icon ? getIcon(view.root, spec.icon)
|
|
40
|
-
: spec.label ? crel("button",
|
|
40
|
+
: spec.label ? crel("button", {type: "button"}, translate(view, spec.label)) as HTMLButtonElement
|
|
41
41
|
: null
|
|
42
42
|
if (!dom) throw new RangeError("MenuItem without icon or label property")
|
|
43
43
|
if (spec.title) {
|
|
@@ -189,6 +189,7 @@ export class Dropdown implements MenuElement {
|
|
|
189
189
|
|
|
190
190
|
let btn = crel(
|
|
191
191
|
"button", {
|
|
192
|
+
type: "button",
|
|
192
193
|
class: prefix + "-dropdown " + (this.options.class || ""),
|
|
193
194
|
style: this.options.css,
|
|
194
195
|
"aria-haspopup": "menu",
|
|
@@ -228,8 +229,8 @@ export class Dropdown implements MenuElement {
|
|
|
228
229
|
} else if (event.key === "Escape") {
|
|
229
230
|
event.preventDefault()
|
|
230
231
|
event.stopPropagation()
|
|
231
|
-
close()
|
|
232
232
|
btn.focus()
|
|
233
|
+
close()
|
|
233
234
|
}
|
|
234
235
|
})
|
|
235
236
|
open.node.addEventListener("focusout", () => {
|
|
@@ -382,7 +383,7 @@ export class DropdownSubmenu implements MenuElement {
|
|
|
382
383
|
this.focusables = items.focusables
|
|
383
384
|
let win = view.dom.ownerDocument.defaultView || window
|
|
384
385
|
|
|
385
|
-
let btn = crel("button", {class: prefix + "-submenu-label"}, translate(view, this.options.label || ""))
|
|
386
|
+
let btn = crel("button", {type: "button", class: prefix + "-submenu-label"}, translate(view, this.options.label || ""))
|
|
386
387
|
let wrap = crel("div", {class: prefix + "-submenu-wrap"}, btn,
|
|
387
388
|
crel("div", {class: prefix + "-submenu"}, items.dom))
|
|
388
389
|
let listeningOnClose: (() => void) | null = null
|