mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 22:55:48 +01:00
[v3] Enable default context menu for certain elements. Use CSS to customise.
This commit is contained in:
parent
9816960995
commit
7f6151d573
11 changed files with 194 additions and 141 deletions
|
|
@ -117,7 +117,13 @@ Webview Window Interface Methods
|
|||
|------------------|---------|-------|-----|-------|
|
||||
| OpenContextMenu | Y | | Y | |
|
||||
| On By Default | | | | |
|
||||
| Control via HTML | | | | |
|
||||
| Control via HTML | Y | | | |
|
||||
|
||||
The default context menu is enabled by default for all elements that are `contentEditable: true`, `<input>` or `<textarea>` tags or have the `--default-contextmenu: true` style set.
|
||||
The `--default-contextmenu: show` style will always show the context menu
|
||||
The `--default-contextmenu: hide` style will always hide the context menu
|
||||
|
||||
Anything nested under a tag with `--default-contextmenu: hide` style will not show the context menu unless it is explicitly set with `--default-contextmenu: show`.
|
||||
|
||||
### Screens
|
||||
|
||||
|
|
|
|||
|
|
@ -3,31 +3,29 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<style>body{ text-align: center; color: white; background-color: rgba(0,0,0,0); user-select: none; -ms-user-select: none; -webkit-user-select: none; }</style>
|
||||
<style>.file{ width: 100px; height: 100px; border: 3px solid black; }</style>
|
||||
<style>body{ text-align: center; color: white; background-color: rgba(0,0,0,255); user-select: none; -ms-user-select: none; -webkit-user-select: none; }</style>
|
||||
<style>.region{ width: 100%; border: 3px solid #00a4db; }</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Context Menu Demo</h1>
|
||||
<br/>
|
||||
<div class="file" id="123abc" data-contextmenu="test" data-contextmenu-data="1">
|
||||
<div class="region" id="123abc" style="--custom-contextmenu: test; --custom-contextmenu-data: 1">
|
||||
<h1>1</h1>
|
||||
</div>
|
||||
<div class="file" id="234abc" data-contextmenu="test" data-contextmenu-data="2">
|
||||
<div class="region" id="234abc" style="--custom-contextmenu: test; --custom-contextmenu-data: 2">
|
||||
<h1>2</h1>
|
||||
</div>
|
||||
<div class="file" id="123abcg" style="--default-contextmenu: show">
|
||||
<div class="region" id="123abcg" style="--default-contextmenu: show">
|
||||
<h1>Default Context Menu shown here</h1>
|
||||
<label>
|
||||
<input type="text" placeholder="context menu hidden here" style="--default-contextmenu: hide"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="file" id="234abcs" style="--default-contextmenu: hide">
|
||||
<div class="region" id="234abcs" style="--default-contextmenu: hide">
|
||||
<h1>Default Context Menu hidden here</h1>
|
||||
<label>
|
||||
<input type="text" placeholder="context menu works here" style="--default-contextmenu: show"/>
|
||||
</label>
|
||||
</div>
|
||||
<div id="results"></div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
// window.addEventListener("dragstart", (event) =>
|
||||
// event.dataTransfer.setData("text/plain", "This text may be dragged")
|
||||
// );
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
|
@ -26,16 +26,9 @@ func main() {
|
|||
})
|
||||
|
||||
mainWindow := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Context Menu Demo",
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInsetUnified,
|
||||
InvisibleTitleBarHeight: 50,
|
||||
},
|
||||
})
|
||||
|
||||
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Context Menu Demo",
|
||||
Title: "Context Menu Demo",
|
||||
Width: 1024,
|
||||
Height: 800,
|
||||
Mac: application.MacWindow{
|
||||
Backdrop: application.MacBackdropTranslucent,
|
||||
TitleBar: application.MacTitleBarHiddenInsetUnified,
|
||||
|
|
@ -46,7 +39,6 @@ func main() {
|
|||
contextMenu := app.NewMenu()
|
||||
contextMenu.Add("Click Me").OnClick(func(data *application.Context) {
|
||||
fmt.Printf("Context menu data: %+v\n", data.ContextMenuData())
|
||||
app.Quit()
|
||||
})
|
||||
|
||||
globalContextMenu := app.NewMenu()
|
||||
|
|
|
|||
|
|
@ -6,36 +6,64 @@ function openContextMenu(id, x, y, data) {
|
|||
void call("OpenContextMenu", {id, x, y, data});
|
||||
}
|
||||
|
||||
export function enableContextMenus(enabled) {
|
||||
if (enabled) {
|
||||
window.addEventListener('contextmenu', contextMenuHandler);
|
||||
} else {
|
||||
window.removeEventListener('contextmenu', contextMenuHandler);
|
||||
}
|
||||
export function setupContextMenus() {
|
||||
window.addEventListener('contextmenu', contextMenuHandler);
|
||||
}
|
||||
|
||||
function contextMenuHandler(event) {
|
||||
let processed = processContextMenu(event.target, event);
|
||||
if (!processed) {
|
||||
let defaultContextMenuAction = window.getComputedStyle(event.target).getPropertyValue("--default-contextmenu");
|
||||
defaultContextMenuAction = defaultContextMenuAction ? defaultContextMenuAction.trim() : "";
|
||||
if (defaultContextMenuAction === 'hide') {
|
||||
event.preventDefault();
|
||||
}
|
||||
// Check for custom context menu
|
||||
let element = event.target;
|
||||
let customContextMenu = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu");
|
||||
customContextMenu = customContextMenu ? customContextMenu.trim() : "";
|
||||
if (customContextMenu) {
|
||||
event.preventDefault();
|
||||
let customContextMenuData = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu-data");
|
||||
openContextMenu(customContextMenu, event.clientX, event.clientY, customContextMenuData);
|
||||
return
|
||||
}
|
||||
|
||||
processDefaultContextMenu(event);
|
||||
}
|
||||
|
||||
function processContextMenu(element, event) {
|
||||
let id = element.getAttribute('data-contextmenu');
|
||||
if (id) {
|
||||
event.preventDefault();
|
||||
openContextMenu(id, event.clientX, event.clientY, element.getAttribute('data-contextmenu-data'));
|
||||
return true;
|
||||
} else {
|
||||
let parent = element.parentElement;
|
||||
if (parent) {
|
||||
processContextMenu(parent, event);
|
||||
}
|
||||
|
||||
/*
|
||||
Default: Show default context menu if contentEditable: true OR text has been selected OR --default-contextmenu: show OR tagname is input or textarea
|
||||
--default-contextmenu: show will always show the context menu
|
||||
--default-contextmenu: hide will always hide the context menu
|
||||
|
||||
Anything nested under a tag with --default-contextmenu: hide will not show the context menu unless it is explicitly set with --default-contextmenu: show
|
||||
*/
|
||||
function processDefaultContextMenu(event) {
|
||||
// Process default context menu
|
||||
let element = event.target;
|
||||
let defaultContextMenuAction = window.getComputedStyle(element).getPropertyValue("--default-contextmenu");
|
||||
defaultContextMenuAction = defaultContextMenuAction ? defaultContextMenuAction.trim() : "";
|
||||
switch(defaultContextMenuAction) {
|
||||
case "show":
|
||||
return;
|
||||
case "hide":
|
||||
event.preventDefault();
|
||||
return;
|
||||
default:
|
||||
// Check if contentEditable is true
|
||||
let contentEditable = element.getAttribute("contentEditable");
|
||||
if (contentEditable && contentEditable.toLowerCase() === "true") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if text has been selected
|
||||
let selection = window.getSelection();
|
||||
if (selection && selection.toString().length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if tagname is input or textarea
|
||||
let tagName = element.tagName.toLowerCase();
|
||||
if (tagName === "input" || tagName === "textarea") {
|
||||
return;
|
||||
}
|
||||
|
||||
// hide default context menu
|
||||
event.preventDefault();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {Plugin, Call, callErrorCallback, callCallback} from "./calls";
|
|||
import {newWindow} from "./window";
|
||||
import {dispatchWailsEvent, Emit, Off, OffAll, On, Once, OnMultiple} from "./events";
|
||||
import {dialogCallback, dialogErrorCallback, Error, Info, OpenFile, Question, SaveFile, Warning,} from "./dialogs";
|
||||
import {enableContextMenus} from "./contextmenu";
|
||||
import {setupContextMenus} from "./contextmenu";
|
||||
import {reloadWML} from "./wml";
|
||||
import {setupDrag, endDrag} from "./drag";
|
||||
|
||||
|
|
@ -85,8 +85,7 @@ if (DEBUG) {
|
|||
console.log("Wails v3.0.0 Debug Mode Enabled");
|
||||
}
|
||||
|
||||
enableContextMenus(true);
|
||||
|
||||
setupContextMenus();
|
||||
setupDrag();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue