Skip to content

Commit e29ea7b

Browse files
committed
🎨 Improve native input context menu #17526
1 parent 9a779dc commit e29ea7b

2 files changed

Lines changed: 63 additions & 43 deletions

File tree

app/electron/main.js

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -102,42 +102,59 @@ const isMatchingContextMenuRequest = (context, request) => {
102102
context.createdAt - request.requestedAt < 1000;
103103
};
104104

105+
const NATIVE_TEXT_CONTEXT_MENU_ROLES = new Set([
106+
"undo", "redo", "cut", "copy", "paste", "pasteAndMatchStyle", "delete", "selectAll",
107+
]);
108+
109+
const getNativeTextContextMenuItems = (contents, request = {}, params) => {
110+
const items = [];
111+
if (!Array.isArray(request.items)) {
112+
return items;
113+
}
114+
const misspelledWord = params?.misspelledWord;
115+
request.items.forEach((item) => {
116+
if (!item || typeof item !== "object") {
117+
return;
118+
}
119+
if (item.type === "addToDictionary") {
120+
if (!misspelledWord) {
121+
return;
122+
}
123+
(params.dictionarySuggestions || []).forEach((suggestion) => {
124+
items.push(new MenuItem({
125+
label: suggestion,
126+
click: () => contents.replaceMisspelling(suggestion),
127+
}));
128+
});
129+
items.push(new MenuItem({
130+
label: item.label,
131+
click: () => {
132+
if (!contents.session.addWordToSpellCheckerDictionary(misspelledWord)) {
133+
writeLog("failed to add word to spell checker dictionary");
134+
}
135+
},
136+
}), {type: "separator"});
137+
return;
138+
}
139+
if (item.type === "separator") {
140+
items.push({type: "separator"});
141+
return;
142+
}
143+
if (!NATIVE_TEXT_CONTEXT_MENU_ROLES.has(item.role)) {
144+
return;
145+
}
146+
items.push(new MenuItem({
147+
role: item.role,
148+
label: item.label,
149+
}));
150+
});
151+
return items;
152+
};
153+
105154
const popupNativeTextContextMenu = (contents, context, request) => {
155+
request = request || {};
106156
const params = context?.params;
107-
const template = [];
108-
if (params?.misspelledWord) {
109-
params.dictionarySuggestions.forEach((suggestion) => {
110-
template.push(new MenuItem({
111-
label: suggestion,
112-
click: () => contents.replaceMisspelling(suggestion),
113-
}));
114-
});
115-
template.push(new MenuItem({
116-
label: request.addToDictionary,
117-
click: () => {
118-
if (!contents.session.addWordToSpellCheckerDictionary(params.misspelledWord)) {
119-
writeLog("failed to add word to spell checker dictionary");
120-
}
121-
},
122-
}), {type: "separator"});
123-
}
124-
template.push(new MenuItem({
125-
role: "undo", label: request.undo
126-
}), new MenuItem({
127-
role: "redo", label: request.redo
128-
}), {type: "separator"}, new MenuItem({
129-
role: "copy", label: request.copy
130-
}), new MenuItem({
131-
role: "cut", label: request.cut
132-
}), new MenuItem({
133-
role: "delete", label: request.delete
134-
}), new MenuItem({
135-
role: "paste", label: request.paste
136-
}), new MenuItem({
137-
role: "pasteAndMatchStyle", label: request.pasteAsPlainText
138-
}), new MenuItem({
139-
role: "selectAll", label: request.selectAll
140-
}));
157+
const template = getNativeTextContextMenuItems(contents, request, params);
141158
const menu = Menu.buildFromTemplate(template);
142159
const options = {
143160
window: BrowserWindow.fromWebContents(contents),

app/src/menus/index.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,18 @@ export class Menus {
3939
x: event.clientX,
4040
y: event.clientY,
4141
requestedAt: Date.now(),
42-
undo: window.siyuan.languages.undo,
43-
redo: window.siyuan.languages.redo,
44-
copy: window.siyuan.languages.copy,
45-
cut: window.siyuan.languages.cut,
46-
delete: window.siyuan.languages.delete,
47-
paste: window.siyuan.languages.paste,
48-
pasteAsPlainText: window.siyuan.languages.pasteAsPlainText,
49-
selectAll: window.siyuan.languages.selectAll,
50-
addToDictionary: window.siyuan.languages.addToDictionary,
42+
items: [
43+
{type: "addToDictionary", label: window.siyuan.languages.addToDictionary},
44+
{role: "undo", label: window.siyuan.languages.undo},
45+
{role: "redo", label: window.siyuan.languages.redo},
46+
{type: "separator"},
47+
{role: "copy", label: window.siyuan.languages.copy},
48+
{role: "cut", label: window.siyuan.languages.cut},
49+
{role: "delete", label: window.siyuan.languages.delete},
50+
{role: "paste", label: window.siyuan.languages.paste},
51+
{role: "pasteAndMatchStyle", label: window.siyuan.languages.pasteAsPlainText},
52+
{role: "selectAll", label: window.siyuan.languages.selectAll},
53+
],
5154
});
5255
/// #endif
5356
event.stopPropagation();

0 commit comments

Comments
 (0)