Fixed dialogs on macOS. Update WML example to use compiled runtime.

This commit is contained in:
Lea Anthony
2024-01-25 21:00:33 +11:00
parent 773bdf8ea2
commit 7674f8eb2b
43 changed files with 395 additions and 1172 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ func main() {
Description: "A demo of the WebviewWindow API",
Assets: application.AlphaAssets,
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
ApplicationShouldTerminateAfterLastWindowClosed: false,
},
})
app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
+1
View File
@@ -129,6 +129,7 @@
font-size: large;
}
</style>
<script src="runtime.js"></script>
</head>
<body style="--webkit-app-region: drag;">
<img class="logo"
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
package runtime
import _ "embed"
//go:embed runtime.js
var runtimeJS []byte
//go:embed runtime.debug.js
var runtimeDebugJS []byte
+2 -2
View File
@@ -21,12 +21,12 @@ tasks:
build:debug:
internal: true
cmds:
- npx esbuild@latest desktop/main.js --bundle --tree-shaking=true --sourcemap=inline --outfile=runtime_debug.js --define:DEBUG=true
- npx esbuild@latest desktop/compiled/main.js --bundle --tree-shaking=true --sourcemap=inline --outfile=../commands/build_assets/runtime/runtime.debug.js --define:DEBUG=true
build:production:
internal: true
cmds:
- npx esbuild@latest desktop/main.js --bundle --tree-shaking=true --minify --outfile=runtime.js --drop:console
- npx esbuild@latest desktop/compiled/main.js --bundle --tree-shaking=true --minify --outfile=../commands/build_assets/runtime/runtime.js --define:DEBUG=false --drop:console
build:all:
internal: true
-28
View File
@@ -1,28 +0,0 @@
//go:build production
package runtime
import _ "embed"
//go:embed runtime.js
var DesktopRuntime []byte
var RuntimeAssetsBundle = &RuntimeAssets{
runtimeDesktopJS: DesktopRuntime,
}
type RuntimeAssets struct {
runtimeDesktopJS []byte
}
func (r *RuntimeAssets) DesktopIPC() []byte {
return []byte("")
}
func (r *RuntimeAssets) WebsocketIPC() []byte {
return []byte("")
}
func (r *RuntimeAssets) RuntimeDesktopJS() []byte {
return r.runtimeDesktopJS
}
-28
View File
@@ -1,28 +0,0 @@
//go:build !production
package runtime
import _ "embed"
//go:embed runtime_debug.js
var DesktopRuntime []byte
var RuntimeAssetsBundle = &RuntimeAssets{
runtimeDesktopJS: DesktopRuntime,
}
type RuntimeAssets struct {
runtimeDesktopJS []byte
}
func (r *RuntimeAssets) DesktopIPC() []byte {
return []byte("")
}
func (r *RuntimeAssets) WebsocketIPC() []byte {
return []byte("")
}
func (r *RuntimeAssets) RuntimeDesktopJS() []byte {
return r.runtimeDesktopJS
}
@@ -1,2 +1,4 @@
events.test.js
node_modules
node_modules
types/drag.d.ts
types/contextmenu.d.ts
@@ -12,14 +12,16 @@ The electron alternative for Go
import { newRuntimeCallerWithID, objectNames } from "./runtime";
import { nanoid } from 'nanoid/non-secure';
const CallBinding = 0;
const call = newRuntimeCallerWithID(objectNames.Call, '');
let callResponses = new Map();
// Setup
window._wails = window._wails || {};
window._wails.callResultHandler = resultHandler;
window._wails.callErrorHandler = errorHandler;
const CallBinding = 0;
const call = newRuntimeCallerWithID(objectNames.Call, '');
let callResponses = new Map();
/**
* Generates a unique ID using the nanoid library.
*
@@ -13,6 +13,9 @@ The electron alternative for Go
import {newRuntimeCallerWithID, objectNames} from "./runtime";
import {IsDebug} from "./system";
// setup
window.addEventListener('contextmenu', contextMenuHandler);
const call = newRuntimeCallerWithID(objectNames.ContextMenu, '');
const ContextMenuOpen = 0;
@@ -20,10 +23,6 @@ function openContextMenu(id, x, y, data) {
void call(ContextMenuOpen, {id, x, y, data});
}
export function setupContextMenus() {
window.addEventListener('contextmenu', contextMenuHandler);
}
function contextMenuHandler(event) {
// Check for custom context menu
let element = event.target;
@@ -73,6 +73,11 @@ The electron alternative for Go
* @property {string} [Pattern] - Pattern to match for the filter, e.g. "*.txt;*.md" for text markdown files.
*/
// setup
window._wails = window._wails || {};
window._wails.dialogErrorCallback = dialogErrorCallback;
window._wails.dialogResultCallback = dialogResultCallback;
import {newRuntimeCallerWithID, objectNames} from "./runtime";
import { nanoid } from 'nanoid/non-secure';
@@ -118,10 +123,6 @@ function dialog(type, options = {}) {
});
}
window._wails = window._wails || {};
window._wails.dialogErrorCallback = dialogErrorCallback;
window._wails.dialogResultCallback = dialogResultCallback;
/**
* Handles the callback from a dialog.
*
@@ -13,15 +13,20 @@ The electron alternative for Go
import {invoke, IsWindows} from "./system";
import {GetFlag} from "./flags";
// Setup
window._wails = window._wails || {};
window._wails.setResizable = setResizable;
window._wails.endDrag = endDrag;
window.addEventListener('mousedown', onMouseDown);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
let shouldDrag = false;
let resizeEdge = null;
let resizable = false;
let defaultCursor = "auto";
window._wails = window._wails || {};
window._wails.setResizable = setResizable;
window._wails.endDrag = endDrag;
export function dragTest(e) {
function dragTest(e) {
let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region");
if (!val || val === "" || val.trim() !== "drag" || e.buttons !== 1) {
return false;
@@ -29,17 +34,11 @@ export function dragTest(e) {
return e.detail === 1;
}
export function setupDrag() {
window.addEventListener('mousedown', onMouseDown);
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
}
export function setResizable(value) {
function setResizable(value) {
resizable = value;
}
export function endDrag() {
function endDrag() {
document.body.style.cursor = 'default';
shouldDrag = false;
}
@@ -176,6 +176,7 @@ export const EventTypes = {
WindowHide: "common:WindowHide",
WindowDPIChanged: "common:WindowDPIChanged",
WindowFilesDropped: "common:WindowFilesDropped",
WindowRuntimeReady: "common:WindowRuntimeReady",
ThemeChanged: "common:ThemeChanged",
},
};
@@ -18,6 +18,10 @@ import {newRuntimeCallerWithID, objectNames} from "./runtime";
import {EventTypes} from "./event_types";
export const Types = EventTypes;
// Setup
window._wails = window._wails || {};
window._wails.dispatchWailsEvent = dispatchWailsEvent;
const call = newRuntimeCallerWithID(objectNames.Events, '');
const EmitMethod = 0;
const eventListeners = new Map();
@@ -42,19 +46,7 @@ export class WailsEvent {
}
}
/**
* Sets up event callbacks for Wails.
*
* @function setupEventCallbacks
*
* @description This method is responsible for setting up event callbacks for Wails. It checks if the global object `_wails` exists on the `window` object, and if not, initializes it
*. It then assigns the `dispatchWailsEvent` function as a property on the `_wails` object.
*
* @returns {undefined} Returns nothing.
*/
export function setupEventCallbacks() {
window._wails = window._wails || {};
window._wails.dispatchWailsEvent = dispatchWailsEvent;
export function setup() {
}
function dispatchWailsEvent(event) {
@@ -58,28 +58,7 @@ describe('Once', () => {
cancel();
})
})
//
// describe('EventsNotify', () => {
// it('should inform a listener', () => {
// const cb = vi.fn()
// EventsOn('a', cb)
// EventsNotify(JSON.stringify({name: 'a', data: ["one", "two", "three"]}))
// expect(cb).toBeCalledTimes(1);
// expect(cb).toHaveBeenLastCalledWith("one", "two", "three");
// expect(window.WailsInvoke).toBeCalledTimes(0);
// })
// })
//
// describe('EventsEmit', () => {
// it('should emit an event', () => {
// EventsEmit('a', 'one', 'two', 'three')
// expect(window.WailsInvoke).toBeCalledTimes(1);
// const calledWith = window.WailsInvoke.calls[0][0];
// expect(calledWith.slice(0, 2)).toBe('EE')
// expect(JSON.parse(calledWith.slice(2))).toStrictEqual({data: ["one", "two", "three"], name: "a"})
// })
// })
//
describe('Off', () => {
beforeEach(() => {
On('a', () => {})
@@ -10,48 +10,6 @@ The electron alternative for Go
/* jshint esversion: 9 */
let flags = new Map();
function convertToMap(obj) {
const map = new Map();
for (const [key, value] of Object.entries(obj)) {
if (typeof value === 'object' && value !== null) {
map.set(key, convertToMap(value)); // Recursively convert nested object
} else {
map.set(key, value);
}
}
return map;
}
fetch("/wails/flags").then((response) => {
response.json().then((data) => {
flags = convertToMap(data);
});
});
function getValueFromMap(keyString) {
const keys = keyString.split('.');
let value = flags;
for (const key of keys) {
if (value instanceof Map) {
value = value.get(key);
} else {
value = value[key];
}
if (value === undefined) {
break;
}
}
return value;
}
/**
* Retrieves the value associated with the specified key from the flag map.
*
@@ -59,5 +17,9 @@ function getValueFromMap(keyString) {
* @return {*} - The value associated with the specified key.
*/
export function GetFlag(keyString) {
return getValueFromMap(keyString);
try {
return window._wails.flags[keyString];
} catch (e) {
throw new Error("Unable to retrieve flag '" + keyString + "': " + e);
}
}
@@ -8,9 +8,9 @@ The electron alternative for Go
(c) Lea Anthony 2019-present
*/
import {setupContextMenus} from "./contextmenu";
import {setupDrag} from "./drag";
import {ByID, ByName, Plugin} from "./calls";
// Setup
window.wails = window.wails || {};
window._wails = window._wails || {};
import * as Application from "./application";
import * as Browser from "./browser";
@@ -23,7 +23,8 @@ import * as WML from './wml';
import * as Events from "./events";
import * as Dialogs from "./dialogs";
import * as Call from "./calls";
import {setupEventCallbacks} from "./events";
import {invoke} from "./system";
export { Application, Browser, Call, Clipboard, Dialogs, Events, Flags, Screens, System, Window, WML};
@@ -59,7 +60,22 @@ export { Application, Browser, Call, Clipboard, Dialogs, Events, Flags, Screens,
***/
let isReady = false
window.wails = {
Application,
Browser,
Call,
Clipboard,
Dialogs,
Events,
Flags,
Screens,
System,
Window,
WML,
};
invoke('wails:runtime:ready');
let isReady = false;
document.addEventListener('DOMContentLoaded', function() {
isReady = true
})
@@ -73,8 +89,5 @@ function whenReady(fn) {
}
whenReady(() => {
setupContextMenus();
setupDrag();
setupEventCallbacks();
WML.Reload();
});
@@ -0,0 +1,13 @@
/**
* Logs a message to the console with custom formatting.
* @param {string} message - The message to be logged.
* @return {void}
*/
export function debugLog(message) {
// eslint-disable-next-line
console.log(
'%c wails3 %c ' + message + ' ',
'background: #aa0000; color: #fff; border-radius: 3px 0px 0px 3px; padding: 1px; font-size: 0.7rem',
'background: #009900; color: #fff; border-radius: 0px 3px 3px 0px; padding: 1px; font-size: 0.7rem'
);
}
@@ -15,6 +15,13 @@ let call = newRuntimeCallerWithID(objectNames.System, '');
const systemIsDarkMode = 0;
const environment = 1;
export function invoke(msg) {
if(window.chrome) {
return window.chrome.webview.postMessage(msg);
}
return window.webkit.messageHandlers.external.postMessage;
}
/**
* @function
* Retrieves the system dark mode status.
@@ -24,7 +31,6 @@ export function IsDarkMode() {
return call(systemIsDarkMode);
}
/**
* Fetches the capabilities of the application from the server.
*
@@ -32,7 +38,7 @@ export function IsDarkMode() {
* @function Capabilities
* @returns {Promise<Object>} A promise that resolves to an object containing the capabilities.
*/
export async function Capabilities() {
export function Capabilities() {
let response = fetch("/wails/capabilities");
return response.json();
}
@@ -52,25 +58,13 @@ export function Environment() {
return call(environment);
}
export let invoke = null;
let environmentCache = null;
Environment()
.then(result => {
environmentCache = result;
invoke = IsWindows() ? window.chrome.webview.postMessage : window.webkit.messageHandlers.external.postMessage;
})
.catch(error => {
console.error(`Error getting Environment: ${error}`);
});
/**
* Checks if the current operating system is Windows.
*
* @return {boolean} True if the operating system is Windows, otherwise false.
*/
export function IsWindows() {
return environmentCache.OS === "windows";
return window._wails.environment.OS === "windows";
}
/**
@@ -79,7 +73,7 @@ export function IsWindows() {
* @returns {boolean} Returns true if the current operating system is Linux, false otherwise.
*/
export function IsLinux() {
return environmentCache.OS === "linux";
return window._wails.environment.OS === "linux";
}
/**
@@ -88,7 +82,7 @@ export function IsLinux() {
* @returns {boolean} True if the environment is macOS, false otherwise.
*/
export function IsMac() {
return environmentCache.OS === "darwin";
return window._wails.environment.OS === "darwin";
}
/**
@@ -96,7 +90,7 @@ export function IsMac() {
* @returns {boolean} True if the current environment architecture is AMD64, false otherwise.
*/
export function IsAMD64() {
return environmentCache.Arch === "amd64";
return window._wails.environment.Arch === "amd64";
}
/**
@@ -105,7 +99,7 @@ export function IsAMD64() {
* @returns {boolean} True if the current architecture is ARM, false otherwise.
*/
export function IsARM() {
return environmentCache.Arch === "arm";
return window._wails.environment.Arch === "arm";
}
/**
@@ -114,9 +108,10 @@ export function IsARM() {
* @returns {boolean} - Returns true if the environment is ARM64 architecture, otherwise returns false.
*/
export function IsARM64() {
return environmentCache.Arch === "arm64";
return window._wails.environment.Arch === "arm64";
}
export function IsDebug() {
return environmentCache.Debug === true;
}
return window._wails.environment.Debug === true;
}
@@ -3,6 +3,7 @@ import {Emit, WailsEvent} from "./events";
import {Question} from "./dialogs";
import {Get} from "./window";
import {OpenURL} from "./browser";
import {debugLog} from "./log";
/**
* Sends an event with the given name and optional data.
@@ -144,7 +145,9 @@ function addWMLOpenBrowserListener() {
* @return {void}
*/
export function Reload() {
console.log("Reloading WML");
if(DEBUG) {
debugLog("Reloading WML");
}
addWMLEventListeners();
addWMLWindowListeners();
addWMLOpenBrowserListener();

Some files were not shown because too many files have changed in this diff Show More