Merge commit '25a157e6614739fbd4df1da3d11d46afe72ae9a8' as 'v2'

This commit is contained in:
Travis McLane
2020-09-01 19:34:51 -05:00
208 changed files with 23636 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
{
"env": {
"browser": true,
"es6": true,
"amd": true,
"node": true,
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2016,
"sourceType": "module",
},
"rules": {
"linebreak-style": 0,
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}

View File

@@ -0,0 +1,22 @@
/* eslint-disable */
module.exports = function (api) {
api.cache(true);
const presets = [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": {
"version": 3,
"proposals": true
}
}
]
];
return {
presets,
};
}

View File

@@ -0,0 +1,107 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { Call } from './calls';
window.backend = {};
/**
Map of this format:
{
packageName: {
structName: {
methodName: {
name: "",
inputs: [
{
type: <type>
}
],
outputs: [
{
type: <type>
}
]
}
}
}
}
*/
export function SetBindings(bindingsMap) {
try {
bindingsMap = JSON.parse(bindingsMap);
} catch (e) {
console.error(e);
}
// Initialise the backend map
window.backend = window.backend || {};
// Iterate package names
Object.keys(bindingsMap).forEach((packageName) => {
// Create inner map if it doesn't exist
window.backend[packageName] = window.backend[packageName] || {};
// Iterate struct names
Object.keys(bindingsMap[packageName]).forEach((structName) => {
// Create inner map if it doesn't exist
window.backend[packageName][structName] = window.backend[packageName][structName] || {};
Object.keys(bindingsMap[packageName][structName]).forEach((methodName) => {
window.backend[packageName][structName][methodName] = function () {
// No timeout by default
var timeout = 0;
// Actual function
function dynamic() {
var args = [].slice.call(arguments);
return Call([packageName, structName, methodName].join('.'), args, timeout);
}
// Allow setting timeout to function
dynamic.setTimeout = function (newTimeout) {
timeout = newTimeout;
};
// Allow getting timeout to function
dynamic.getTimeout = function () {
return timeout;
};
return dynamic;
}();
});
});
});
}
// /**
// * Determines if the given identifier is valid Javascript
// *
// * @param {boolean} name
// * @returns
// */
// function isValidIdentifier(name) {
// // Don't xss yourself :-)
// try {
// new Function('var ' + name);
// return true;
// } catch (e) {
// return false;
// }
// }

View File

@@ -0,0 +1,34 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { SendMessage } from 'ipc';
/**
* Opens the given URL in the system browser
*
* @export
* @param {string} url
* @returns
*/
export function OpenURL(url) {
return SendMessage('RBU' + url);
}
/**
* Opens the given filename using the system's default file handler
*
* @export
* @param {sting} filename
* @returns
*/
export function OpenFile(filename) {
return SendMessage('runtime:browser:openfile', filename);
}

View File

@@ -0,0 +1,156 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { Debug } from './log';
import { SendMessage } from 'ipc';
var callbacks = {};
/**
* Returns a number from the native browser random function
*
* @returns number
*/
function cryptoRandom() {
var array = new Uint32Array(1);
return window.crypto.getRandomValues(array)[0];
}
/**
* Returns a number using da old-skool Math.Random
* I likes to call it LOLRandom
*
* @returns number
*/
function basicRandom() {
return Math.random() * 9007199254740991;
}
// Pick a random number function based on browser capability
var randomFunc;
if (window.crypto) {
randomFunc = cryptoRandom;
} else {
randomFunc = basicRandom;
}
/**
* Call sends a message to the backend to call the binding with the
* given data. A promise is returned and will be completed when the
* backend responds. This will be resolved when the call was successful
* or rejected if an error is passed back.
* There is a timeout mechanism. If the call doesn't respond in the given
* time (in milliseconds) then the promise is rejected.
*
* @export
* @param {string} name
* @param {string} args
* @param {number=} timeout
* @returns
*/
export function Call(name, args, timeout) {
// Timeout infinite by default
if (timeout == null || timeout == undefined) {
timeout = 0;
}
// Create a promise
return new Promise(function (resolve, reject) {
// Create a unique callbackID
var callbackID;
do {
callbackID = name + '-' + randomFunc();
} while (callbacks[callbackID]);
// Set timeout
if (timeout > 0) {
var timeoutHandle = setTimeout(function () {
reject(Error('Call to ' + name + ' timed out. Request ID: ' + callbackID));
}, timeout);
}
// Store callback
callbacks[callbackID] = {
timeoutHandle: timeoutHandle,
reject: reject,
resolve: resolve
};
try {
const payload = {
name,
args,
callbackID,
};
// Make the call
SendMessage('C' + JSON.stringify(payload));
} catch (e) {
// eslint-disable-next-line
console.error(e);
}
});
}
/**
* Called by the backend to return data to a previously called
* binding invocation
*
* @export
* @param {string} incomingMessage
*/
export function Callback(incomingMessage) {
// Decode the message - Credit: https://stackoverflow.com/a/13865680
//incomingMessage = decodeURIComponent(incomingMessage.replace(/\s+/g, '').replace(/[0-9a-f]{2}/g, '%$&'));
// Parse the message
var message;
try {
message = JSON.parse(incomingMessage);
} catch (e) {
const error = `Invalid JSON passed to callback: ${e.message}. Message: ${incomingMessage}`;
Debug(error);
throw new Error(error);
}
var callbackID = message.callbackid;
var callbackData = callbacks[callbackID];
if (!callbackData) {
const error = `Callback '${callbackID}' not registered!!!`;
console.error(error); // eslint-disable-line
throw new Error(error);
}
clearTimeout(callbackData.timeoutHandle);
delete callbacks[callbackID];
if (message.error) {
callbackData.reject(message.error);
} else {
callbackData.resolve(message.result);
}
}
/**
* SystemCall is used to call wails methods from the frontend
*
* @export
* @param {string} method
* @param {any[]=} data
* @returns
*/
export function SystemCall(method, data) {
return Call('.wails.' + method, data);
}

View File

@@ -0,0 +1,35 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { SetBindings } from './bindings';
import { Init } from './main';
// Setup global error handler
window.onerror = function (/*msg, url, lineNo, columnNo, error*/) {
// window.wails.Log.Error('**** Caught Unhandled Error ****');
// window.wails.Log.Error('Message: ' + msg);
// window.wails.Log.Error('URL: ' + url);
// window.wails.Log.Error('Line No: ' + lineNo);
// window.wails.Log.Error('Column No: ' + columnNo);
// window.wails.Log.Error('error: ' + error);
(function () { window.wails.Log.Error(new Error().stack); })();
};
// Initialise the Runtime
Init();
// Load Bindings if they exist
if (window.wailsbindings) {
SetBindings(window.wailsbindings);
}
// Emit loaded event. Leaving this for now. It will show any errors if runtime fails to load.
window.wails.Events.Emit('wails:loaded');

View File

@@ -0,0 +1,202 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { Error } from './log';
import { SendMessage } from 'ipc';
// Defines a single listener with a maximum number of times to callback
/**
* The Listener class defines a listener! :-)
*
* @class Listener
*/
class Listener {
/**
* Creates an instance of Listener.
* @param {function} callback
* @param {number} maxCallbacks
* @memberof Listener
*/
constructor(callback, maxCallbacks) {
// Default of -1 means infinite
maxCallbacks = maxCallbacks || -1;
// Callback invokes the callback with the given data
// Returns true if this listener should be destroyed
this.Callback = (data) => {
callback.apply(null, data);
// If maxCallbacks is infinite, return false (do not destroy)
if (maxCallbacks === -1) {
return false;
}
// Decrement maxCallbacks. Return true if now 0, otherwise false
maxCallbacks -= 1;
return maxCallbacks === 0;
};
}
}
var eventListeners = {};
/**
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
*
* @export
* @param {string} eventName
* @param {function} callback
* @param {number} maxCallbacks
*/
export function OnMultiple(eventName, callback, maxCallbacks) {
eventListeners[eventName] = eventListeners[eventName] || [];
const thisListener = new Listener(callback, maxCallbacks);
console.log('Pushing event listener: ' + eventName);
eventListeners[eventName].push(thisListener);
}
/**
* Registers an event listener that will be invoked every time the event is emitted
*
* @export
* @param {string} eventName
* @param {function} callback
*/
export function On(eventName, callback) {
OnMultiple(eventName, callback);
}
/**
* Registers an event listener that will be invoked once then destroyed
*
* @export
* @param {string} eventName
* @param {function} callback
*/
export function Once(eventName, callback) {
OnMultiple(eventName, callback, 1);
}
/**
* Notify informs frontend listeners that an event was emitted with the given data
*
* @export
* @param {string} encoded notification message
*/
export function Notify(notifyMessage) {
// Parse the message
var message;
try {
message = JSON.parse(notifyMessage);
} catch (e) {
const error = 'Invalid JSON passed to Notify: ' + notifyMessage;
throw new Error(error);
}
var eventName = message.name;
// Check if we have any listeners for this event
if (eventListeners[eventName]) {
// Keep a list of listener indexes to destroy
const newEventListenerList = eventListeners[eventName].slice();
// Iterate listeners
for (let count = 0; count < eventListeners[eventName].length; count += 1) {
// Get next listener
const listener = eventListeners[eventName][count];
var data = message.data;
// Do the callback
const destroy = listener.Callback(data);
if (destroy) {
// if the listener indicated to destroy itself, add it to the destroy list
newEventListenerList.splice(count, 1);
}
}
// Update callbacks with new list of listners
eventListeners[eventName] = newEventListenerList;
}
}
/**
* Emit an event with the given name and data
*
* @export
* @param {string} eventName
*/
export function Emit(eventName) {
// Calculate the data
if (arguments.length > 1) {
// Notify backend
const payload = {
name: eventName,
data: [].slice.apply(arguments).slice(1),
};
SendMessage('Ej' + JSON.stringify(payload));
} else {
SendMessage('ej' + eventName);
}
}
// Callbacks for the heartbeat calls
const heartbeatCallbacks = {};
/**
* Heartbeat emits the event `eventName`, every `timeInMilliseconds` milliseconds until
* the event is acknowledged via `Event.Acknowledge`. Once this happens, `callback` is invoked ONCE
*
* @export
* @param {string} eventName
* @param {number} timeInMilliseconds
* @param {function} callback
*/
export function Heartbeat(eventName, timeInMilliseconds, callback) {
// Declare interval variable
let interval = null;
// Setup callback
function dynamicCallback() {
// Kill interval
clearInterval(interval);
// Callback
callback();
}
// Register callback
heartbeatCallbacks[eventName] = dynamicCallback;
// Start emitting the event
interval = setInterval(function () {
Emit(eventName);
}, timeInMilliseconds);
}
/**
* Acknowledges a heartbeat event by name
*
* @export
* @param {string} eventName
*/
export function Acknowledge(eventName) {
// If we are waiting for acknowledgement for this event type
if (heartbeatCallbacks[eventName]) {
// Acknowledge!
heartbeatCallbacks[eventName]();
} else {
throw new Error(`Cannot acknowledge unknown heartbeat '${eventName}'`);
}
}

View File

@@ -0,0 +1,76 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { SendMessage } from 'ipc';
/**
* Sends a log message to the backend with the given level + message
*
* @param {string} level
* @param {string} message
*/
function sendLogMessage(level, message) {
// Log Message format:
// l[type][message]
SendMessage('L' + level + message);
}
/**
* Log the given debug message with the backend
*
* @export
* @param {string} message
*/
export function Debug(message) {
sendLogMessage('D', message);
}
/**
* Log the given info message with the backend
*
* @export
* @param {string} message
*/
export function Info(message) {
sendLogMessage('I', message);
}
/**
* Log the given warning message with the backend
*
* @export
* @param {string} message
*/
export function Warning(message) {
sendLogMessage('W', message);
}
/**
* Log the given error message with the backend
*
* @export
* @param {string} message
*/
export function Error(message) {
sendLogMessage('E', message);
}
/**
* Log the given fatal message with the backend
*
* @export
* @param {string} message
*/
export function Fatal(message) {
sendLogMessage('F', message);
}

View File

@@ -0,0 +1,47 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import * as Log from './log';
import * as Browser from './browser';
import { On, OnMultiple, Emit, Notify, Heartbeat, Acknowledge } from './events';
import { Callback } from './calls';
import { AddScript, InjectCSS } from './utils';
import { AddIPCListener } from 'ipc';
import * as Platform from 'platform';
export function Init() {
// Backend is where the Go struct wrappers get bound to
window.backend = {};
// Initialise global if not already
window.wails = {
System: Platform.System,
Log,
Browser,
Events: {
On,
OnMultiple,
Emit,
Heartbeat,
Acknowledge,
},
_: {
Callback,
Notify,
AddScript,
InjectCSS,
Init,
AddIPCListener
}
};
// Do platform specific Init
Platform.Init();
}

View File

@@ -0,0 +1,182 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { Init } from './main';
import { SetBindings } from './bindings';
function init() {
// Bridge object
window.wailsbridge = {
reconnectOverlay: null,
reconnectTimer: 300,
wsURL: 'ws://' + window.location.hostname + ':8080/ws',
connectionState: null,
config: {},
websocket: null,
callback: null,
overlayHTML:
'<div class="wails-reconnect-overlay"><div class="wails-reconnect-overlay-content"><div class="wails-reconnect-overlay-title">Wails Bridge</div><br><div class="wails-reconnect-overlay-loadingspinner"></div><br><div id="wails-reconnect-overlay-message">Waiting for backend</div></div></div>',
overlayCSS:
'.wails-reconnect-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);font-family:sans-serif;display:none;z-index:999999}.wails-reconnect-overlay-content{padding:20px 30px;text-align:center;width:20em;position:relative;height:14em;border-radius:1em;margin:5% auto 0;background-color:#fff;box-shadow:1px 1px 20px 3px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC8AAAAuCAMAAACPpbA7AAAAqFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQAAAAAAAAEBAQAAAAAAAAAAAAEBAQEBAQDAwMBAQEAAAABAQEAAAAAAAAAAAABAQEAAAAAAAACAgICAgIBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEAAAACAgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQWKCj6oAAAAN3RSTlMALiIqDhkGBAswJjP0GxP6NR4W9/ztjRDMhWU50G9g5eHXvbZ9XEI9xZTcqZl2aldKo55QwoCvZUgzhAAAAs9JREFUSMeNleeWqjAUhU0BCaH3Itiw9zKT93+zG02QK1hm/5HF+jzZJ6fQe6cyXE+jg9X7o9wxuylIIf4Tv2V3+bOrEXnf8dwQ/KQIGDN2/S+4OmVCVXL/ScBnfibxURqIByP/hONE8r8T+bDMlQ98KSl7Y8hzjpS8v1qtDh8u5f8KQpGpfnPPhqG8JeogN37Hq9eaN2xRhIwAaGnvws8F1ShxqK5ob2twYi1FAMD4rXsYtnC/JEiRbl4cUrCWhnMCLRFemXezXbb59QK4WASOsm6n2W1+4CBT2JmtzQ6fsrbGubR/NFbd2g5Y179+5w/GEHaKsHjYCet7CgrXU3txarNC7YxOVJtIj4/ERzMdZfzc31hp+8cD6eGILgarZY9uZ12hAs03vfBD9C171gS5Omz7OcvxALQIn4u8RRBBBcsi9WW2woO9ipLgfzpYlggg3ZRdROUC8KT7QLqq3W9KB5BbdFVg4929kdwp6+qaZnMCCNBdj+NyN1W885Ry/AL3D4AQbsVV4noCiM/C83kyYq80XlDAYQtralOiDzoRAHlotWl8q2tjvYlOgcg1A8jEApZa+C06TBdAz2Qv0wu11I/zZOyJQ6EwGez2P2b8PIQr1hwwnAZsAxwA4UAYOyXUxM/xp6tHAn4GUmPGM9R28oVxgC0e/zQJJI6DyhyZ1r7uzRQhpcW7x7vTaWSzKSG6aep77kroTEl3U81uSVaUTtgEINfC8epx+Q4F9SpplHG84Ek6m4RAq9/TLkOBrxyeuddZhHvGIp1XXfFy3Z3vtwNblKGiDn+J+92vwwABHghj7HnzlS1H5kB49AZvdGCFgiBPq69qfXPr3y++yilF0ON4R8eR7spAsLpZ95NqAW5tab1c4vkZm6aleajchMwYTdILQQTwE2OV411ZM9WztDjPql12caBi6gDpUKmDd4U1XNdQxZ4LIXQ5/Tr4P7I9tYcFrDK3AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center}.wails-reconnect-overlay-title{font-size:2em}.wails-reconnect-overlay-message{font-size:1.3em}.wails-reconnect-overlay-loadingspinner{pointer-events:none;width:2.5em;height:2.5em;border:.4em solid transparent;border-color:#3E67EC #eee #eee;border-radius:50%;animation:loadingspin 1s linear infinite;margin:auto;padding:2.5em}@keyframes loadingspin{100%{transform:rotate(360deg)}}',
log: function (message) {
// eslint-disable-next-line
console.log(
'%c wails bridge %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'
);
}
};
}
// Adapted from webview - thanks zserge!
function injectCSS(css) {
var elem = document.createElement('style');
elem.setAttribute('type', 'text/css');
if (elem.styleSheet) {
elem.styleSheet.cssText = css;
} else {
elem.appendChild(document.createTextNode(css));
}
var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(elem);
}
// Creates a node in the Dom
function createNode(parent, elementType, id, className, content) {
var d = document.createElement(elementType);
if (id) {
d.id = id;
}
if (className) {
d.className = className;
}
if (content) {
d.innerHTML = content;
}
parent.appendChild(d);
return d;
}
// Sets up the overlay
function setupOverlay() {
var body = document.body;
var wailsBridgeNode = createNode(body, 'div', 'wails-bridge');
wailsBridgeNode.innerHTML = window.wailsbridge.overlayHTML;
// Inject the overlay CSS
injectCSS(window.wailsbridge.overlayCSS);
}
// Start the Wails Bridge
function startBridge() {
// Setup the overlay
setupOverlay();
window.wailsbridge.websocket = null;
window.wailsbridge.connectTimer = null;
window.wailsbridge.reconnectOverlay = document.querySelector(
'.wails-reconnect-overlay'
);
window.wailsbridge.connectionState = 'disconnected';
// Shows the overlay
function showReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = 'block';
}
// Hides the overlay
function hideReconnectOverlay() {
window.wailsbridge.reconnectOverlay.style.display = 'none';
}
// Handles incoming websocket connections
function handleConnect() {
window.wailsbridge.log('Connected to backend');
hideReconnectOverlay();
clearInterval(window.wailsbridge.connectTimer);
window.wailsbridge.websocket.onclose = handleDisconnect;
window.wailsbridge.websocket.onmessage = handleMessage;
window.wailsbridge.connectionState = 'connected';
}
// Handles websocket disconnects
function handleDisconnect() {
window.wailsbridge.log('Disconnected from backend');
window.wailsbridge.websocket = null;
window.wailsbridge.connectionState = 'disconnected';
showReconnectOverlay();
connect();
}
// Try to connect to the backend every 300ms (default value).
// Change this value in the main wailsbridge object.
function connect() {
window.wailsbridge.connectTimer = setInterval(function () {
if (window.wailsbridge.websocket == null) {
window.wailsbridge.websocket = new WebSocket(window.wailsbridge.wsURL);
window.wailsbridge.websocket.onopen = handleConnect;
window.wailsbridge.websocket.onerror = function (e) {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
window.wailsbridge.websocket = null;
return false;
};
}
}, window.wailsbridge.reconnectTimer);
}
function handleMessage(message) {
switch (message.data[0]) {
case 'e':
case 'E':
window.wails._.Notify(message.data.slice(1));
break;
case 'R':
window.wails._.Callback(message.data.slice(1));
break;
default:
window.wails.Log.Error('Unknown message type received: ' + message.data[0]);
}
}
// Start by showing the overlay...
showReconnectOverlay();
// ...and attempt to connect
connect();
}
function start() {
// Set up the bridge
init();
// Start Bridge
startBridge();
// Load bindings
window.wailspreinit = function () {
if (window.wailsbindings) {
SetBindings(window.wailsbindings);
}
};
Init();
// Save the binding script
window.SetBindings = SetBindings;
}
// Start your engines!
start();

View File

@@ -0,0 +1,38 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import { Emit } from './events';
export function AddScript(js, callbackID) {
var script = document.createElement('script');
script.text = js;
document.body.appendChild(script);
if (callbackID) {
Emit(callbackID);
}
}
// Adapted from webview - thanks zserge!
export function InjectCSS(css) {
try {
var elem = document.createElement('style');
elem.setAttribute('type', 'text/css');
if (elem.styleSheet) {
elem.styleSheet.cssText = css;
} else {
elem.appendChild(document.createTextNode(css));
}
var head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(elem);
} catch (e) {
console.log(e);
}
}

View File

@@ -0,0 +1,41 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
import * as Platform from 'platform';
// IPC Listeners
var listeners = [];
/**
* Adds a listener to IPC messages
* @param {function} callback
*/
export function AddIPCListener(callback) {
listeners.push(callback);
}
/**
* SendMessage sends the given message to the backend
*
* @param {string} message
*/
export function SendMessage(message) {
// Call Platform specific invoke method
Platform.SendMessage(message);
// Also send to listeners
if (listeners.length > 0) {
for (var i = 0; i < listeners.length; i++) {
listeners[i](message);
}
}
}

View File

@@ -0,0 +1,41 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Initialises platform specific code
*/
export const System = {
Platform: "linux",
AppType: "desktop"
}
export function SendMessage(message) {
window.webkit.messageHandlers.external.postMessage(message);
}
export function Init() {
// Setup drag handler
// Based on code from: https://github.com/patr0nus/DeskGap
window.addEventListener('mousedown', function (e) {
var currentElement = e.target;
while (currentElement != null) {
if (currentElement.hasAttribute('data-wails-no-drag')) {
break;
} else if (currentElement.hasAttribute('data-wails-drag')) {
window.webkit.messageHandlers.windowDrag.postMessage(null);
break;
}
currentElement = currentElement.parentElement;
}
});
}

5988
v2/internal/runtime/js/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
{
"name": "wails-runtime",
"version": "1.0.0",
"description": "The Javascript Wails Runtime",
"main": "index.js",
"scripts": {
"build:desktop": "./node_modules/.bin/eslint core/ && ./node_modules/.bin/webpack --env desktop --colors",
"build:server": "./node_modules/.bin/eslint core/ && ./node_modules/.bin/webpack --env server --colors",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wailsapp/runtime.git"
},
"keywords": [
"Wails",
"Go",
"Javascript",
"Runtime"
],
"browserslist": [
"> 5%",
"IE 9"
],
"author": "Lea Anthony <lea.anthony@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/wailsapp/runtime/issues"
},
"homepage": "https://github.com/wailsapp/runtime#readme",
"devDependencies": {
"@babel/cli": "^7.7.7",
"@babel/core": "^7.7.7",
"@babel/plugin-transform-object-assign": "^7.7.4",
"@babel/preset-env": "^7.7.7",
"babel-loader": "^8.0.6",
"babel-preset-minify": "^0.5.1",
"core-js": "^3.6.1",
"eslint": "^6.8.0",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10"
}
}

View File

@@ -0,0 +1 @@
77a32d4461a2cad598edfd551fe64dcd

View File

@@ -0,0 +1 @@
bridge.js

View File

@@ -0,0 +1,3 @@
# Wails Runtime
This module is the Javascript runtime library for the [Wails](https://wails.app) framework. It is intended to be installed as part of a [Wails](https://wails.app) project, not a standalone module.

View File

@@ -0,0 +1,37 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Opens the given URL in the system browser
*
* @export
* @param {string} url
* @returns
*/
function OpenURL(url) {
return window.wails.Browser.OpenURL(url);
}
/**
* Opens the given filename using the system's default file handler
*
* @export
* @param {sting} filename
* @returns
*/
function OpenFile(filename) {
return window.wails.Browser.OpenFile(filename);
}
module.exports = {
OpenURL: OpenURL,
OpenFile: OpenFile
};

View File

@@ -0,0 +1,90 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Registers an event listener that will be invoked `maxCallbacks` times before being destroyed
*
* @export
* @param {string} eventName
* @param {function} callback
* @param {number} maxCallbacks
*/
function OnMultiple(eventName, callback, maxCallbacks) {
window.wails.Events.OnMultiple(eventName, callback, maxCallbacks);
}
/**
* Registers an event listener that will be invoked every time the event is emitted
*
* @export
* @param {string} eventName
* @param {function} callback
*/
function On(eventName, callback) {
OnMultiple(eventName, callback);
}
/**
* Registers an event listener that will be invoked once then destroyed
*
* @export
* @param {string} eventName
* @param {function} callback
*/
function Once(eventName, callback) {
OnMultiple(eventName, callback, 1);
}
/**
* Emit an event with the given name and data
*
* @export
* @param {string} eventName
*/
function Emit(eventName) {
var args = [eventName].slice.call(arguments);
return window.wails.Events.Emit.apply(null, args);
}
/**
* Heartbeat emits the event `eventName`, every `timeInMilliseconds` milliseconds until
* the event is acknowledged via `Event.Acknowledge`. Once this happens, `callback` is invoked ONCE
*
* @export
* @param {string} eventName
* @param {number} timeInMilliseconds
* @param {function} callback
*/
function Heartbeat(eventName, timeInMilliseconds, callback) {
window.wails.Events.Heartbeat(eventName, timeInMilliseconds, callback);
}
/**
* Acknowledges a heartbeat event by name
*
* @export
* @param {string} eventName
*/
function Acknowledge(eventName) {
return window.wails.Events.Acknowledge(eventName);
}
module.exports = {
OnMultiple: OnMultiple,
On: On,
Once: Once,
Emit: Emit,
Heartbeat: Heartbeat,
Acknowledge: Acknowledge
};

View File

@@ -0,0 +1,21 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Initialises the Wails runtime
*
* @param {function} callback
*/
function Init(callback) {
window.wails._.Init(callback);
}
module.exports = Init;

View File

@@ -0,0 +1,70 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Log the given debug message with the backend
*
* @export
* @param {string} message
*/
function Debug(message) {
window.wails.Log.Debug(message);
}
/**
* Log the given info message with the backend
*
* @export
* @param {string} message
*/
function Info(message) {
window.wails.Log.Info(message);
}
/**
* Log the given warning message with the backend
*
* @export
* @param {string} message
*/
function Warning(message) {
window.wails.Log.Warning(message);
}
/**
* Log the given error message with the backend
*
* @export
* @param {string} message
*/
function Error(message) {
window.wails.Log.Error(message);
}
/**
* Log the given fatal message with the backend
*
* @export
* @param {string} message
*/
function Fatal(message) {
window.wails.Log.Fatal(message);
}
module.exports = {
Debug: Debug,
Info: Info,
Warning: Warning,
Error: Error,
Fatal: Fatal
};

View File

@@ -0,0 +1,22 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
const Log = require('./log');
const Browser = require('./browser');
const Events = require('./events');
const Init = require('./init');
module.exports = {
Log: Log,
Browser: Browser,
Events: Events,
Init: Init
};

View File

@@ -0,0 +1,28 @@
{
"name": "@wailsapp/runtime",
"version": "1.0.10",
"description": "Wails Javascript runtime library",
"main": "main.js",
"types": "runtime.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/wailsapp/wails.git"
},
"keywords": [
"Wails",
"Javascript",
"Go"
],
"author": "Lea Anthony <lea.anthony@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/wailsapp/wails/issues"
},
"homepage": "https://github.com/wailsapp/wails#readme",
"devDependencies": {
"dts-gen": "^0.5.8"
}
}

View File

@@ -0,0 +1,26 @@
export = wailsapp__runtime;
declare const wailsapp__runtime: {
Browser: {
OpenFile(filename: string): Promise<any>;
OpenURL(url: string): Promise<any>;
};
Events: {
Acknowledge(eventName: string): void;
Emit(eventName: string): void;
Heartbeat(eventName: string, timeInMilliseconds: number, callback: () => void): void;
On(eventName: string, callback: () => void): void;
OnMultiple(eventName: string, callback: () => void, maxCallbacks: number): void;
Once(eventName: string, callback: () => void): void;
};
Init(callback: () => void): void;
Log: {
Debug(message: string): void;
Error(message: string): void;
Fatal(message: string): void;
Info(message: string): void;
Warning(message: string): void;
};
};

View File

@@ -0,0 +1,52 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
// IPC Listeners
var listeners = [];
/**
* Adds a listener to IPC messages
* @param {function} callback
*/
export function AddIPCListener(callback) {
listeners.push(callback);
}
/**
* Invoke sends the given message to the backend
*
* @param {string} message
*/
function Invoke(message) {
if (window.wailsbridge && window.wailsbridge.websocket) {
window.wailsbridge.websocket.send(JSON.stringify(message));
} else {
console.log('Invoke called with: ' + message + ' but no runtime is available');
}
// Also send to listeners
if (listeners.length > 0) {
for (var i = 0; i < listeners.length; i++) {
listeners[i](message);
}
}
}
/**
* Sends a message to the backend based on the given type, payload and callbackID
*
* @export
* @param {string} message
*/
export function SendMessage(message) {
Invoke(message);
}

View File

@@ -0,0 +1,21 @@
/*
_ __ _ __
| | / /___ _(_) /____
| | /| / / __ `/ / / ___/
| |/ |/ / /_/ / / (__ )
|__/|__/\__,_/_/_/____/
The lightweight framework for web-like apps
(c) Lea Anthony 2019-present
*/
/* jshint esversion: 6 */
/**
* Initialises platform specific code
*/
export const System = {
Platform: "linux",
AppType: "server"
}
export function Init() { }

View File

@@ -0,0 +1,4 @@
/* eslint-disable */
module.exports = (env) => {
return require(`./webpack.${env}.js`);
};

View File

@@ -0,0 +1,51 @@
/* eslint-disable */
const path = require('path');
const platform = process.env.WAILSPLATFORM;
if (!platform) {
console.error("FATAL: Environment variable WAILSPLATFORM not set!");
process.exit(1);
}
module.exports = {
entry: './core/desktop',
mode: 'production',
output: {
path: path.resolve(__dirname, '..', 'assets'),
filename: 'desktop.js',
library: 'Wails'
},
resolve: {
alias: {
ipc$: path.resolve(__dirname, 'desktop/ipc.js'),
platform$: path.resolve(__dirname, `desktop/${platform}.js`)
}
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@babel/plugin-transform-object-assign'],
presets: [
[
'@babel/preset-env',
{
'useBuiltIns': 'entry',
'corejs': {
'version': 3,
'proposals': true
}
}
]
]
}
}
}
]
}
};

View File

@@ -0,0 +1,54 @@
/* eslint-disable */
const path = require('path');
const platform = process.env.WAILSPLATFORM;
if (!platform) {
console.error("FATAL: Environment variable WAILSPLATFORM not set!");
process.exit(1);
}
module.exports = {
entry: './core/server',
mode: 'production',
output: {
path: path.resolve(__dirname, '..', 'assets'),
filename: 'server.js',
library: 'Wails'
},
resolve: {
alias: {
ipc$: path.resolve(__dirname, 'server/ipc.js'),
platform$: path.resolve(__dirname, `server/${platform}.js`)
}
},
module: {
rules: [
{
test: /\.m?js$/,
include: [
path.resolve(__dirname, "server"),
],
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
plugins: ['@babel/plugin-transform-object-assign'],
presets: [
[
'@babel/preset-env',
{
'useBuiltIns': 'entry',
'corejs': {
'version': 3,
'proposals': true
}
}
]
]
}
}
}
]
}
};