@wailsio/runtime 3.0.0-alpha.65 → 3.0.0-alpha.66
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/{src → dist}/application.js +2 -16
- package/dist/browser.js +20 -0
- package/dist/callable.js +144 -0
- package/dist/calls.js +194 -0
- package/dist/cancellable.js +792 -0
- package/dist/clipboard.js +30 -0
- package/dist/contextmenu.js +80 -0
- package/{src → dist}/create.js +2 -33
- package/dist/dialogs.js +134 -0
- package/dist/drag.js +222 -0
- package/dist/event_types.js +229 -0
- package/dist/events.js +101 -0
- package/dist/flags.js +23 -0
- package/dist/index.js +38 -0
- package/dist/listener.js +44 -0
- package/{src → dist}/nanoid.js +7 -11
- package/dist/runtime.js +63 -0
- package/dist/screens.js +38 -0
- package/dist/system.js +116 -0
- package/{src → dist}/utils.js +29 -20
- package/dist/window.js +438 -0
- package/{src → dist}/wml.js +51 -122
- package/package.json +43 -19
- package/types/application.d.ts +3 -10
- package/types/browser.d.ts +4 -4
- package/types/callable.d.ts +3 -0
- package/types/calls.d.ts +43 -49
- package/types/cancellable.d.ts +434 -0
- package/types/clipboard.d.ts +6 -5
- package/types/contextmenu.d.ts +1 -0
- package/types/create.d.ts +6 -27
- package/types/dialogs.d.ts +99 -143
- package/types/drag.d.ts +1 -0
- package/types/event_types.d.ts +218 -219
- package/types/events.d.ts +45 -250
- package/types/flags.d.ts +3 -3
- package/types/index.d.ts +16 -14
- package/types/listener.d.ts +9 -0
- package/types/nanoid.d.ts +1 -1
- package/types/runtime.d.ts +18 -26
- package/types/screens.d.ts +42 -76
- package/types/system.d.ts +50 -79
- package/types/utils.d.ts +15 -8
- package/types/window.d.ts +110 -225
- package/types/wml.d.ts +2 -6
- package/docs/.nojekyll +0 -1
- package/docs/assets/highlight.css +0 -22
- package/docs/assets/icons.js +0 -15
- package/docs/assets/icons.svg +0 -1
- package/docs/assets/main.js +0 -59
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1415
- package/docs/classes/Call.RuntimeError.html +0 -11
- package/docs/classes/Events.WailsEvent.html +0 -4
- package/docs/functions/Application.Hide.html +0 -2
- package/docs/functions/Application.Quit.html +0 -2
- package/docs/functions/Application.Show.html +0 -2
- package/docs/functions/Browser.OpenURL.html +0 -3
- package/docs/functions/Call.ByID.html +0 -8
- package/docs/functions/Call.ByName.html +0 -6
- package/docs/functions/Call.Call.html +0 -11
- package/docs/functions/Clipboard.SetText.html +0 -6
- package/docs/functions/Clipboard.Text.html +0 -3
- package/docs/functions/Create.Any.html +0 -2
- package/docs/functions/Create.Array.html +0 -4
- package/docs/functions/Create.ByteSlice.html +0 -3
- package/docs/functions/Create.Map.html +0 -4
- package/docs/functions/Create.Nullable.html +0 -3
- package/docs/functions/Create.Struct.html +0 -3
- package/docs/functions/Dialogs.Error.html +0 -5
- package/docs/functions/Dialogs.Info.html +0 -5
- package/docs/functions/Dialogs.OpenFile.html +0 -3
- package/docs/functions/Dialogs.Question.html +0 -5
- package/docs/functions/Dialogs.SaveFile.html +0 -3
- package/docs/functions/Dialogs.Warning.html +0 -5
- package/docs/functions/Events.Emit.html +0 -6
- package/docs/functions/Events.Off.html +0 -4
- package/docs/functions/Events.OffAll.html +0 -3
- package/docs/functions/Events.On.html +0 -7
- package/docs/functions/Events.OnMultiple.html +0 -8
- package/docs/functions/Events.Once.html +0 -7
- package/docs/functions/Events.setup.html +0 -1
- package/docs/functions/Flags.GetFlag.html +0 -6
- package/docs/functions/Screens.GetAll.html +0 -3
- package/docs/functions/Screens.GetCurrent.html +0 -3
- package/docs/functions/Screens.GetPrimary.html +0 -3
- package/docs/functions/System.Capabilities.html +0 -4
- package/docs/functions/System.Environment.html +0 -5
- package/docs/functions/System.IsAMD64.html +0 -3
- package/docs/functions/System.IsARM.html +0 -3
- package/docs/functions/System.IsARM64.html +0 -5
- package/docs/functions/System.IsDarkMode.html +0 -5
- package/docs/functions/System.IsDebug.html +0 -1
- package/docs/functions/System.IsLinux.html +0 -3
- package/docs/functions/System.IsMac.html +0 -3
- package/docs/functions/System.IsWindows.html +0 -3
- package/docs/functions/System.invoke.html +0 -1
- package/docs/functions/WML.Enable.html +0 -2
- package/docs/functions/WML.Reload.html +0 -2
- package/docs/functions/init.html +0 -1
- package/docs/index.html +0 -5
- package/docs/interfaces/Call.CallOptions.html +0 -7
- package/docs/interfaces/Dialogs.Button.html +0 -7
- package/docs/interfaces/Dialogs.FileFilter.html +0 -5
- package/docs/interfaces/Dialogs.MessageDialogOptions.html +0 -9
- package/docs/interfaces/Dialogs.OpenFileDialogOptions.html +0 -33
- package/docs/interfaces/Dialogs.SaveFileDialogOptions.html +0 -35
- package/docs/interfaces/Screens.Rect.html +0 -9
- package/docs/interfaces/Screens.Screen.html +0 -25
- package/docs/interfaces/Screens.Size.html +0 -5
- package/docs/interfaces/System.EnvironmentInfo.html +0 -11
- package/docs/interfaces/System.OSInfo.html +0 -9
- package/docs/modules/Application.html +0 -4
- package/docs/modules/Browser.html +0 -2
- package/docs/modules/Call.html +0 -6
- package/docs/modules/Clipboard.html +0 -3
- package/docs/modules/Create.html +0 -7
- package/docs/modules/Dialogs.html +0 -12
- package/docs/modules/Events.html +0 -10
- package/docs/modules/Flags.html +0 -2
- package/docs/modules/Screens.html +0 -7
- package/docs/modules/System.html +0 -14
- package/docs/modules/WML.html +0 -3
- package/docs/modules.html +0 -14
- package/docs/variables/Events.Types.html +0 -1
- package/docs/variables/Window.html +0 -2
- package/src/browser.js +0 -24
- package/src/calls.js +0 -221
- package/src/clipboard.js +0 -35
- package/src/contextmenu.js +0 -97
- package/src/dialogs.js +0 -200
- package/src/drag.js +0 -119
- package/src/event_types.js +0 -219
- package/src/events.js +0 -140
- package/src/flags.js +0 -25
- package/src/index.js +0 -60
- package/src/runtime.js +0 -92
- package/src/screens.js +0 -71
- package/src/system.js +0 -143
- package/src/window.js +0 -638
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ __ _ __
|
|
3
|
+
| | / /___ _(_) /____
|
|
4
|
+
| | /| / / __ `/ / / ___/
|
|
5
|
+
| |/ |/ / /_/ / / (__ )
|
|
6
|
+
|__/|__/\__,_/_/_/____/
|
|
7
|
+
The electron alternative for Go
|
|
8
|
+
(c) Lea Anthony 2019-present
|
|
9
|
+
*/
|
|
10
|
+
import { newRuntimeCaller, objectNames } from "./runtime.js";
|
|
11
|
+
const call = newRuntimeCaller(objectNames.Clipboard);
|
|
12
|
+
const ClipboardSetText = 0;
|
|
13
|
+
const ClipboardText = 1;
|
|
14
|
+
/**
|
|
15
|
+
* Sets the text to the Clipboard.
|
|
16
|
+
*
|
|
17
|
+
* @param text - The text to be set to the Clipboard.
|
|
18
|
+
* @return A Promise that resolves when the operation is successful.
|
|
19
|
+
*/
|
|
20
|
+
export function SetText(text) {
|
|
21
|
+
return call(ClipboardSetText, { text });
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the Clipboard text
|
|
25
|
+
*
|
|
26
|
+
* @returns A promise that resolves with the text from the Clipboard.
|
|
27
|
+
*/
|
|
28
|
+
export function Text() {
|
|
29
|
+
return call(ClipboardText);
|
|
30
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ __ _ __
|
|
3
|
+
| | / /___ _(_) /____
|
|
4
|
+
| | /| / / __ `/ / / ___/
|
|
5
|
+
| |/ |/ / /_/ / / (__ )
|
|
6
|
+
|__/|__/\__,_/_/_/____/
|
|
7
|
+
The electron alternative for Go
|
|
8
|
+
(c) Lea Anthony 2019-present
|
|
9
|
+
*/
|
|
10
|
+
import { newRuntimeCaller, objectNames } from "./runtime.js";
|
|
11
|
+
import { IsDebug } from "./system.js";
|
|
12
|
+
import { eventTarget } from "./utils";
|
|
13
|
+
// setup
|
|
14
|
+
window.addEventListener('contextmenu', contextMenuHandler);
|
|
15
|
+
const call = newRuntimeCaller(objectNames.ContextMenu);
|
|
16
|
+
const ContextMenuOpen = 0;
|
|
17
|
+
function openContextMenu(id, x, y, data) {
|
|
18
|
+
void call(ContextMenuOpen, { id, x, y, data });
|
|
19
|
+
}
|
|
20
|
+
function contextMenuHandler(event) {
|
|
21
|
+
const target = eventTarget(event);
|
|
22
|
+
// Check for custom context menu
|
|
23
|
+
const customContextMenu = window.getComputedStyle(target).getPropertyValue("--custom-contextmenu").trim();
|
|
24
|
+
if (customContextMenu) {
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
const data = window.getComputedStyle(target).getPropertyValue("--custom-contextmenu-data");
|
|
27
|
+
openContextMenu(customContextMenu, event.clientX, event.clientY, data);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
processDefaultContextMenu(event, target);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/*
|
|
34
|
+
--default-contextmenu: auto; (default) will show the default context menu if contentEditable is true OR text has been selected OR element is input or textarea
|
|
35
|
+
--default-contextmenu: show; will always show the default context menu
|
|
36
|
+
--default-contextmenu: hide; will always hide the default context menu
|
|
37
|
+
|
|
38
|
+
This rule is inherited like normal CSS rules, so nesting works as expected
|
|
39
|
+
*/
|
|
40
|
+
function processDefaultContextMenu(event, target) {
|
|
41
|
+
// Debug builds always show the menu
|
|
42
|
+
if (IsDebug()) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Process default context menu
|
|
46
|
+
switch (window.getComputedStyle(target).getPropertyValue("--default-contextmenu").trim()) {
|
|
47
|
+
case 'show':
|
|
48
|
+
return;
|
|
49
|
+
case 'hide':
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Check if contentEditable is true
|
|
54
|
+
if (target.isContentEditable) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Check if text has been selected
|
|
58
|
+
const selection = window.getSelection();
|
|
59
|
+
const hasSelection = selection && selection.toString().length > 0;
|
|
60
|
+
if (hasSelection) {
|
|
61
|
+
for (let i = 0; i < selection.rangeCount; i++) {
|
|
62
|
+
const range = selection.getRangeAt(i);
|
|
63
|
+
const rects = range.getClientRects();
|
|
64
|
+
for (let j = 0; j < rects.length; j++) {
|
|
65
|
+
const rect = rects[j];
|
|
66
|
+
if (document.elementFromPoint(rect.left, rect.top) === target) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Check if tag is input or textarea.
|
|
73
|
+
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
74
|
+
if (hasSelection || (!target.readOnly && !target.disabled)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// hide default context menu
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
}
|
package/{src → dist}/create.js
RENAMED
|
@@ -7,42 +7,28 @@
|
|
|
7
7
|
The electron alternative for Go
|
|
8
8
|
(c) Lea Anthony 2019-present
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
|
-
/* jshint esversion: 9 */
|
|
12
|
-
|
|
13
10
|
/**
|
|
14
11
|
* Any is a dummy creation function for simple or unknown types.
|
|
15
|
-
* @template T
|
|
16
|
-
* @param {any} source
|
|
17
|
-
* @returns {T}
|
|
18
12
|
*/
|
|
19
13
|
export function Any(source) {
|
|
20
|
-
return
|
|
14
|
+
return source;
|
|
21
15
|
}
|
|
22
|
-
|
|
23
16
|
/**
|
|
24
17
|
* ByteSlice is a creation function that replaces
|
|
25
18
|
* null strings with empty strings.
|
|
26
|
-
* @param {any} source
|
|
27
|
-
* @returns {string}
|
|
28
19
|
*/
|
|
29
20
|
export function ByteSlice(source) {
|
|
30
|
-
return
|
|
21
|
+
return ((source == null) ? "" : source);
|
|
31
22
|
}
|
|
32
|
-
|
|
33
23
|
/**
|
|
34
24
|
* Array takes a creation function for an arbitrary type
|
|
35
25
|
* and returns an in-place creation function for an array
|
|
36
26
|
* whose elements are of that type.
|
|
37
|
-
* @template T
|
|
38
|
-
* @param {(source: any) => T} element
|
|
39
|
-
* @returns {(source: any) => T[]}
|
|
40
27
|
*/
|
|
41
28
|
export function Array(element) {
|
|
42
29
|
if (element === Any) {
|
|
43
30
|
return (source) => (source === null ? [] : source);
|
|
44
31
|
}
|
|
45
|
-
|
|
46
32
|
return (source) => {
|
|
47
33
|
if (source === null) {
|
|
48
34
|
return [];
|
|
@@ -53,21 +39,15 @@ export function Array(element) {
|
|
|
53
39
|
return source;
|
|
54
40
|
};
|
|
55
41
|
}
|
|
56
|
-
|
|
57
42
|
/**
|
|
58
43
|
* Map takes creation functions for two arbitrary types
|
|
59
44
|
* and returns an in-place creation function for an object
|
|
60
45
|
* whose keys and values are of those types.
|
|
61
|
-
* @template K, V
|
|
62
|
-
* @param {(source: any) => K} key
|
|
63
|
-
* @param {(source: any) => V} value
|
|
64
|
-
* @returns {(source: any) => { [_: K]: V }}
|
|
65
46
|
*/
|
|
66
47
|
export function Map(key, value) {
|
|
67
48
|
if (value === Any) {
|
|
68
49
|
return (source) => (source === null ? {} : source);
|
|
69
50
|
}
|
|
70
|
-
|
|
71
51
|
return (source) => {
|
|
72
52
|
if (source === null) {
|
|
73
53
|
return {};
|
|
@@ -78,29 +58,19 @@ export function Map(key, value) {
|
|
|
78
58
|
return source;
|
|
79
59
|
};
|
|
80
60
|
}
|
|
81
|
-
|
|
82
61
|
/**
|
|
83
62
|
* Nullable takes a creation function for an arbitrary type
|
|
84
63
|
* and returns a creation function for a nullable value of that type.
|
|
85
|
-
* @template T
|
|
86
|
-
* @param {(source: any) => T} element
|
|
87
|
-
* @returns {(source: any) => (T | null)}
|
|
88
64
|
*/
|
|
89
65
|
export function Nullable(element) {
|
|
90
66
|
if (element === Any) {
|
|
91
67
|
return Any;
|
|
92
68
|
}
|
|
93
|
-
|
|
94
69
|
return (source) => (source === null ? null : element(source));
|
|
95
70
|
}
|
|
96
|
-
|
|
97
71
|
/**
|
|
98
72
|
* Struct takes an object mapping field names to creation functions
|
|
99
73
|
* and returns an in-place creation function for a struct.
|
|
100
|
-
* @template {{ [_: string]: ((source: any) => any) }} T
|
|
101
|
-
* @template {{ [Key in keyof T]?: ReturnType<T[Key]> }} U
|
|
102
|
-
* @param {T} createField
|
|
103
|
-
* @returns {(source: any) => U}
|
|
104
74
|
*/
|
|
105
75
|
export function Struct(createField) {
|
|
106
76
|
let allAny = true;
|
|
@@ -113,7 +83,6 @@ export function Struct(createField) {
|
|
|
113
83
|
if (allAny) {
|
|
114
84
|
return Any;
|
|
115
85
|
}
|
|
116
|
-
|
|
117
86
|
return (source) => {
|
|
118
87
|
for (const name in createField) {
|
|
119
88
|
if (name in source) {
|
package/dist/dialogs.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ __ _ __
|
|
3
|
+
| | / /___ _(_) /____
|
|
4
|
+
| | /| / / __ `/ / / ___/
|
|
5
|
+
| |/ |/ / /_/ / / (__ )
|
|
6
|
+
|__/|__/\__,_/_/_/____/
|
|
7
|
+
The electron alternative for Go
|
|
8
|
+
(c) Lea Anthony 2019-present
|
|
9
|
+
*/
|
|
10
|
+
import { newRuntimeCaller, objectNames } from "./runtime.js";
|
|
11
|
+
import { nanoid } from './nanoid.js';
|
|
12
|
+
// setup
|
|
13
|
+
window._wails = window._wails || {};
|
|
14
|
+
window._wails.dialogErrorCallback = dialogErrorCallback;
|
|
15
|
+
window._wails.dialogResultCallback = dialogResultCallback;
|
|
16
|
+
const call = newRuntimeCaller(objectNames.Dialog);
|
|
17
|
+
const dialogResponses = new Map();
|
|
18
|
+
// Define constants from the `methods` object in Title Case
|
|
19
|
+
const DialogInfo = 0;
|
|
20
|
+
const DialogWarning = 1;
|
|
21
|
+
const DialogError = 2;
|
|
22
|
+
const DialogQuestion = 3;
|
|
23
|
+
const DialogOpenFile = 4;
|
|
24
|
+
const DialogSaveFile = 5;
|
|
25
|
+
/**
|
|
26
|
+
* Handles the result of a dialog request.
|
|
27
|
+
*
|
|
28
|
+
* @param id - The id of the request to handle the result for.
|
|
29
|
+
* @param data - The result data of the request.
|
|
30
|
+
* @param isJSON - Indicates whether the data is JSON or not.
|
|
31
|
+
*/
|
|
32
|
+
function dialogResultCallback(id, data, isJSON) {
|
|
33
|
+
let resolvers = getAndDeleteResponse(id);
|
|
34
|
+
if (!resolvers) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (isJSON) {
|
|
38
|
+
try {
|
|
39
|
+
resolvers.resolve(JSON.parse(data));
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
resolvers.reject(new TypeError("could not parse result: " + err.message, { cause: err }));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
resolvers.resolve(data);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Handles the error from a dialog request.
|
|
51
|
+
*
|
|
52
|
+
* @param id - The id of the promise handler.
|
|
53
|
+
* @param message - An error message.
|
|
54
|
+
*/
|
|
55
|
+
function dialogErrorCallback(id, message) {
|
|
56
|
+
var _a;
|
|
57
|
+
(_a = getAndDeleteResponse(id)) === null || _a === void 0 ? void 0 : _a.reject(new window.Error(message));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Retrieves and removes the response associated with the given ID from the dialogResponses map.
|
|
61
|
+
*
|
|
62
|
+
* @param id - The ID of the response to be retrieved and removed.
|
|
63
|
+
* @returns The response object associated with the given ID, if any.
|
|
64
|
+
*/
|
|
65
|
+
function getAndDeleteResponse(id) {
|
|
66
|
+
const response = dialogResponses.get(id);
|
|
67
|
+
dialogResponses.delete(id);
|
|
68
|
+
return response;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generates a unique ID using the nanoid library.
|
|
72
|
+
*
|
|
73
|
+
* @returns A unique ID that does not exist in the dialogResponses set.
|
|
74
|
+
*/
|
|
75
|
+
function generateID() {
|
|
76
|
+
let result;
|
|
77
|
+
do {
|
|
78
|
+
result = nanoid();
|
|
79
|
+
} while (dialogResponses.has(result));
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Presents a dialog of specified type with the given options.
|
|
84
|
+
*
|
|
85
|
+
* @param type - Dialog type.
|
|
86
|
+
* @param options - Options for the dialog.
|
|
87
|
+
* @returns A promise that resolves with result of dialog.
|
|
88
|
+
*/
|
|
89
|
+
function dialog(type, options = {}) {
|
|
90
|
+
const id = generateID();
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
dialogResponses.set(id, { resolve, reject });
|
|
93
|
+
call(type, Object.assign({ "dialog-id": id }, options)).catch((err) => {
|
|
94
|
+
dialogResponses.delete(id);
|
|
95
|
+
reject(err);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Presents an info dialog.
|
|
101
|
+
*
|
|
102
|
+
* @param options - Dialog options
|
|
103
|
+
* @returns A promise that resolves with the label of the chosen button.
|
|
104
|
+
*/
|
|
105
|
+
export function Info(options) { return dialog(DialogInfo, options); }
|
|
106
|
+
/**
|
|
107
|
+
* Presents a warning dialog.
|
|
108
|
+
*
|
|
109
|
+
* @param options - Dialog options.
|
|
110
|
+
* @returns A promise that resolves with the label of the chosen button.
|
|
111
|
+
*/
|
|
112
|
+
export function Warning(options) { return dialog(DialogWarning, options); }
|
|
113
|
+
/**
|
|
114
|
+
* Presents an error dialog.
|
|
115
|
+
*
|
|
116
|
+
* @param options - Dialog options.
|
|
117
|
+
* @returns A promise that resolves with the label of the chosen button.
|
|
118
|
+
*/
|
|
119
|
+
export function Error(options) { return dialog(DialogError, options); }
|
|
120
|
+
/**
|
|
121
|
+
* Presents a question dialog.
|
|
122
|
+
*
|
|
123
|
+
* @param options - Dialog options.
|
|
124
|
+
* @returns A promise that resolves with the label of the chosen button.
|
|
125
|
+
*/
|
|
126
|
+
export function Question(options) { return dialog(DialogQuestion, options); }
|
|
127
|
+
export function OpenFile(options) { var _a; return (_a = dialog(DialogOpenFile, options)) !== null && _a !== void 0 ? _a : []; }
|
|
128
|
+
/**
|
|
129
|
+
* Presents a file selection dialog to pick a file to save.
|
|
130
|
+
*
|
|
131
|
+
* @param options - Dialog options.
|
|
132
|
+
* @returns Selected file, or a blank string if no file has been selected.
|
|
133
|
+
*/
|
|
134
|
+
export function SaveFile(options) { return dialog(DialogSaveFile, options); }
|
package/dist/drag.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/*
|
|
2
|
+
_ __ _ __
|
|
3
|
+
| | / /___ _(_) /____
|
|
4
|
+
| | /| / / __ `/ / / ___/
|
|
5
|
+
| |/ |/ / /_/ / / (__ )
|
|
6
|
+
|__/|__/\__,_/_/_/____/
|
|
7
|
+
The electron alternative for Go
|
|
8
|
+
(c) Lea Anthony 2019-present
|
|
9
|
+
*/
|
|
10
|
+
import { invoke, IsWindows } from "./system.js";
|
|
11
|
+
import { GetFlag } from "./flags.js";
|
|
12
|
+
import { canTrackButtons, eventTarget } from "./utils.js";
|
|
13
|
+
// Setup
|
|
14
|
+
let canDrag = false;
|
|
15
|
+
let dragging = false;
|
|
16
|
+
let resizable = false;
|
|
17
|
+
let canResize = false;
|
|
18
|
+
let resizing = false;
|
|
19
|
+
let resizeEdge = "";
|
|
20
|
+
let defaultCursor = "auto";
|
|
21
|
+
let buttons = 0;
|
|
22
|
+
const buttonsTracked = canTrackButtons();
|
|
23
|
+
window._wails = window._wails || {};
|
|
24
|
+
window._wails.setResizable = (value) => {
|
|
25
|
+
resizable = value;
|
|
26
|
+
if (!resizable) {
|
|
27
|
+
// Stop resizing if in progress.
|
|
28
|
+
canResize = resizing = false;
|
|
29
|
+
setResize();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
window.addEventListener('mousedown', update, { capture: true });
|
|
33
|
+
window.addEventListener('mousemove', update, { capture: true });
|
|
34
|
+
window.addEventListener('mouseup', update, { capture: true });
|
|
35
|
+
for (const ev of ['click', 'contextmenu', 'dblclick']) {
|
|
36
|
+
window.addEventListener(ev, suppressEvent, { capture: true });
|
|
37
|
+
}
|
|
38
|
+
function suppressEvent(event) {
|
|
39
|
+
// Suppress click events while resizing or dragging.
|
|
40
|
+
if (dragging || resizing) {
|
|
41
|
+
event.stopImmediatePropagation();
|
|
42
|
+
event.stopPropagation();
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Use constants to avoid comparing strings multiple times.
|
|
47
|
+
const MouseDown = 0;
|
|
48
|
+
const MouseUp = 1;
|
|
49
|
+
const MouseMove = 2;
|
|
50
|
+
function update(event) {
|
|
51
|
+
// Windows suppresses mouse events at the end of dragging or resizing,
|
|
52
|
+
// so we need to be smart and synthesize button events.
|
|
53
|
+
let eventType, eventButtons = event.buttons;
|
|
54
|
+
switch (event.type) {
|
|
55
|
+
case 'mousedown':
|
|
56
|
+
eventType = MouseDown;
|
|
57
|
+
if (!buttonsTracked) {
|
|
58
|
+
eventButtons = buttons | (1 << event.button);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case 'mouseup':
|
|
62
|
+
eventType = MouseUp;
|
|
63
|
+
if (!buttonsTracked) {
|
|
64
|
+
eventButtons = buttons & ~(1 << event.button);
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
eventType = MouseMove;
|
|
69
|
+
if (!buttonsTracked) {
|
|
70
|
+
eventButtons = buttons;
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
let released = buttons & ~eventButtons;
|
|
75
|
+
let pressed = eventButtons & ~buttons;
|
|
76
|
+
buttons = eventButtons;
|
|
77
|
+
// Synthesize a release-press sequence if we detect a press of an already pressed button.
|
|
78
|
+
if (eventType === MouseDown && !(pressed & event.button)) {
|
|
79
|
+
released |= (1 << event.button);
|
|
80
|
+
pressed |= (1 << event.button);
|
|
81
|
+
}
|
|
82
|
+
// Suppress all button events during dragging and resizing,
|
|
83
|
+
// unless this is a mouseup event that is ending a drag action.
|
|
84
|
+
if (eventType !== MouseMove // Fast path for mousemove
|
|
85
|
+
&& resizing
|
|
86
|
+
|| (dragging
|
|
87
|
+
&& (eventType === MouseDown
|
|
88
|
+
|| event.button !== 0))) {
|
|
89
|
+
event.stopImmediatePropagation();
|
|
90
|
+
event.stopPropagation();
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
}
|
|
93
|
+
// Handle releases
|
|
94
|
+
if (released & 1) {
|
|
95
|
+
primaryUp(event);
|
|
96
|
+
}
|
|
97
|
+
// Handle presses
|
|
98
|
+
if (pressed & 1) {
|
|
99
|
+
primaryDown(event);
|
|
100
|
+
}
|
|
101
|
+
// Handle mousemove
|
|
102
|
+
if (eventType === MouseMove) {
|
|
103
|
+
onMouseMove(event);
|
|
104
|
+
}
|
|
105
|
+
;
|
|
106
|
+
}
|
|
107
|
+
function primaryDown(event) {
|
|
108
|
+
// Reset readiness state.
|
|
109
|
+
canDrag = false;
|
|
110
|
+
canResize = false;
|
|
111
|
+
// Ignore repeated clicks on macOS and Linux.
|
|
112
|
+
if (!IsWindows()) {
|
|
113
|
+
if (event.type === 'mousedown' && event.button === 0 && event.detail !== 1) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (resizeEdge) {
|
|
118
|
+
// Ready to resize if the primary button was pressed for the first time.
|
|
119
|
+
canResize = true;
|
|
120
|
+
// Do not start drag operations when on resize edges.
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Retrieve target element
|
|
124
|
+
const target = eventTarget(event);
|
|
125
|
+
// Ready to drag if the primary button was pressed for the first time on a draggable element.
|
|
126
|
+
// Ignore clicks on the scrollbar.
|
|
127
|
+
const style = window.getComputedStyle(target);
|
|
128
|
+
canDrag = (style.getPropertyValue("--wails-draggable").trim() === "drag"
|
|
129
|
+
&& (event.offsetX - parseFloat(style.paddingLeft) < target.clientWidth
|
|
130
|
+
&& event.offsetY - parseFloat(style.paddingTop) < target.clientHeight));
|
|
131
|
+
}
|
|
132
|
+
function primaryUp(event) {
|
|
133
|
+
// Stop dragging and resizing.
|
|
134
|
+
canDrag = false;
|
|
135
|
+
dragging = false;
|
|
136
|
+
canResize = false;
|
|
137
|
+
resizing = false;
|
|
138
|
+
}
|
|
139
|
+
const cursorForEdge = Object.freeze({
|
|
140
|
+
"se-resize": "nwse-resize",
|
|
141
|
+
"sw-resize": "nesw-resize",
|
|
142
|
+
"nw-resize": "nwse-resize",
|
|
143
|
+
"ne-resize": "nesw-resize",
|
|
144
|
+
"w-resize": "ew-resize",
|
|
145
|
+
"n-resize": "ns-resize",
|
|
146
|
+
"s-resize": "ns-resize",
|
|
147
|
+
"e-resize": "ew-resize",
|
|
148
|
+
});
|
|
149
|
+
function setResize(edge) {
|
|
150
|
+
if (edge) {
|
|
151
|
+
if (!resizeEdge) {
|
|
152
|
+
defaultCursor = document.body.style.cursor;
|
|
153
|
+
}
|
|
154
|
+
document.body.style.cursor = cursorForEdge[edge];
|
|
155
|
+
}
|
|
156
|
+
else if (!edge && resizeEdge) {
|
|
157
|
+
document.body.style.cursor = defaultCursor;
|
|
158
|
+
}
|
|
159
|
+
resizeEdge = edge || "";
|
|
160
|
+
}
|
|
161
|
+
function onMouseMove(event) {
|
|
162
|
+
if (canResize && resizeEdge) {
|
|
163
|
+
// Start resizing.
|
|
164
|
+
resizing = true;
|
|
165
|
+
invoke("wails:resize:" + resizeEdge);
|
|
166
|
+
}
|
|
167
|
+
else if (canDrag) {
|
|
168
|
+
// Start dragging.
|
|
169
|
+
dragging = true;
|
|
170
|
+
invoke("wails:drag");
|
|
171
|
+
}
|
|
172
|
+
if (dragging || resizing) {
|
|
173
|
+
// Either drag or resize is ongoing,
|
|
174
|
+
// reset readiness and stop processing.
|
|
175
|
+
canDrag = canResize = false;
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (!resizable || !IsWindows()) {
|
|
179
|
+
if (resizeEdge) {
|
|
180
|
+
setResize();
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5;
|
|
185
|
+
const resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5;
|
|
186
|
+
// Extra pixels for the corner areas.
|
|
187
|
+
const cornerExtra = GetFlag("resizeCornerExtra") || 10;
|
|
188
|
+
const rightBorder = (window.outerWidth - event.clientX) < resizeHandleWidth;
|
|
189
|
+
const leftBorder = event.clientX < resizeHandleWidth;
|
|
190
|
+
const topBorder = event.clientY < resizeHandleHeight;
|
|
191
|
+
const bottomBorder = (window.outerHeight - event.clientY) < resizeHandleHeight;
|
|
192
|
+
// Adjust for corner areas.
|
|
193
|
+
const rightCorner = (window.outerWidth - event.clientX) < (resizeHandleWidth + cornerExtra);
|
|
194
|
+
const leftCorner = event.clientX < (resizeHandleWidth + cornerExtra);
|
|
195
|
+
const topCorner = event.clientY < (resizeHandleHeight + cornerExtra);
|
|
196
|
+
const bottomCorner = (window.outerHeight - event.clientY) < (resizeHandleHeight + cornerExtra);
|
|
197
|
+
if (!leftCorner && !topCorner && !bottomCorner && !rightCorner) {
|
|
198
|
+
// Optimisation: out of all corner areas implies out of borders.
|
|
199
|
+
setResize();
|
|
200
|
+
}
|
|
201
|
+
// Detect corners.
|
|
202
|
+
else if (rightCorner && bottomCorner)
|
|
203
|
+
setResize("se-resize");
|
|
204
|
+
else if (leftCorner && bottomCorner)
|
|
205
|
+
setResize("sw-resize");
|
|
206
|
+
else if (leftCorner && topCorner)
|
|
207
|
+
setResize("nw-resize");
|
|
208
|
+
else if (topCorner && rightCorner)
|
|
209
|
+
setResize("ne-resize");
|
|
210
|
+
// Detect borders.
|
|
211
|
+
else if (leftBorder)
|
|
212
|
+
setResize("w-resize");
|
|
213
|
+
else if (topBorder)
|
|
214
|
+
setResize("n-resize");
|
|
215
|
+
else if (bottomBorder)
|
|
216
|
+
setResize("s-resize");
|
|
217
|
+
else if (rightBorder)
|
|
218
|
+
setResize("e-resize");
|
|
219
|
+
// Out of border area.
|
|
220
|
+
else
|
|
221
|
+
setResize();
|
|
222
|
+
}
|