|
1 | | -eel = { |
2 | | - _host: window.location.origin, |
| 1 | +class Eel { |
| 2 | + #host = window.location.origin; |
3 | 3 |
|
4 | | - set_host: function (hostname) { |
5 | | - eel._host = hostname |
6 | | - }, |
| 4 | + set_host(hostname) { this.#host = hostname; } |
7 | 5 |
|
8 | | - expose: function(f, name) { |
9 | | - if(name === undefined){ |
10 | | - name = f.toString(); |
11 | | - let i = 'function '.length, j = name.indexOf('('); |
| 6 | + expose(func, name) { |
| 7 | + if (name === undefined) { |
| 8 | + name = func.toString(); |
| 9 | + const i = 'function '.length; |
| 10 | + const j = name.indexOf('('); |
12 | 11 | name = name.substring(i, j).trim(); |
13 | 12 | } |
| 13 | + this.#exposed_functions[name] = func; |
| 14 | + } |
| 15 | + |
| 16 | + guid = () => this.#guid; |
14 | 17 |
|
15 | | - eel._exposed_functions[name] = f; |
16 | | - }, |
| 18 | + constructor() { this.#init(); } |
17 | 19 |
|
18 | | - guid: function() { |
19 | | - return eel._guid; |
20 | | - }, |
| 20 | + #py_functions // Injected by Python |
21 | 21 |
|
22 | | - // These get dynamically added by library when file is served |
23 | | - /** _py_functions **/ |
24 | | - /** _start_geometry **/ |
| 22 | + #start_geometry // Injected by Python |
25 | 23 |
|
26 | | - _guid: ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => |
27 | | - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) |
28 | | - ), |
| 24 | + #guid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, char => |
| 25 | + (char ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> char / 4) |
| 26 | + .toString(16) |
| 27 | + ); |
29 | 28 |
|
30 | | - _exposed_functions: {}, |
| 29 | + #exposed_functions = {}; |
31 | 30 |
|
32 | | - _mock_queue: [], |
| 31 | + #mock_queue = []; |
33 | 32 |
|
34 | | - _mock_py_functions: function() { |
35 | | - for(let i = 0; i < eel._py_functions.length; i++) { |
36 | | - let name = eel._py_functions[i]; |
37 | | - eel[name] = function() { |
38 | | - let call_object = eel._call_object(name, arguments); |
39 | | - eel._mock_queue.push(call_object); |
40 | | - return eel._call_return(call_object); |
| 33 | + #mock_py_functions() { |
| 34 | + for (let i = 0; i < this.#py_functions.length; i++) { |
| 35 | + const name = this.#py_functions[i]; |
| 36 | + this[name] = function() { |
| 37 | + const call_object = this.#call_object(name, arguments); |
| 38 | + this.#mock_queue.push(call_object); |
| 39 | + return this.#call_return(call_object); |
41 | 40 | } |
42 | 41 | } |
43 | | - }, |
44 | | - |
45 | | - _import_py_function: function(name) { |
46 | | - let func_name = name; |
47 | | - eel[name] = function() { |
48 | | - let call_object = eel._call_object(func_name, arguments); |
49 | | - eel._websocket.send(eel._toJSON(call_object)); |
50 | | - return eel._call_return(call_object); |
| 42 | + } |
| 43 | + |
| 44 | + #import_py_function(name) { |
| 45 | + this[name] = function() { |
| 46 | + const call_object = this.#call_object(name, arguments); |
| 47 | + this.#websocket.send(this.#to_json(call_object)); |
| 48 | + return this.#call_return(call_object); |
51 | 49 | } |
52 | | - }, |
| 50 | + } |
53 | 51 |
|
54 | | - _call_number: 0, |
| 52 | + #call_number = 0; |
55 | 53 |
|
56 | | - _call_return_callbacks: {}, |
| 54 | + #call_return_callbacks = {}; |
57 | 55 |
|
58 | | - _call_object: function(name, args) { |
59 | | - let arg_array = []; |
60 | | - for(let i = 0; i < args.length; i++){ |
| 56 | + #call_object(name, args) { |
| 57 | + const arg_array = []; |
| 58 | + for (let i = 0; i < args.length; i++) |
61 | 59 | arg_array.push(args[i]); |
62 | | - } |
63 | | - |
64 | | - let call_id = (eel._call_number += 1) + Math.random(); |
| 60 | + const call_id = (this.#call_number += 1) + Math.random(); |
65 | 61 | return {'call': call_id, 'name': name, 'args': arg_array}; |
66 | | - }, |
| 62 | + } |
67 | 63 |
|
68 | | - _sleep: function(ms) { |
| 64 | + #sleep(ms) { |
69 | 65 | return new Promise(resolve => setTimeout(resolve, ms)); |
70 | | - }, |
71 | | - |
72 | | - _toJSON: function(obj) { |
73 | | - return JSON.stringify(obj, (k, v) => v === undefined ? null : v); |
74 | | - }, |
75 | | - |
76 | | - _call_return: function(call) { |
77 | | - return function(callback = null) { |
78 | | - if(callback != null) { |
79 | | - eel._call_return_callbacks[call.call] = {resolve: callback}; |
80 | | - } else { |
81 | | - return new Promise(function(resolve, reject) { |
82 | | - eel._call_return_callbacks[call.call] = {resolve: resolve, reject: reject}; |
83 | | - }); |
84 | | - } |
85 | | - } |
86 | | - }, |
| 66 | + } |
87 | 67 |
|
88 | | - _position_window: function(page) { |
89 | | - let size = eel._start_geometry['default'].size; |
90 | | - let position = eel._start_geometry['default'].position; |
| 68 | + #to_json(obj) { |
| 69 | + return JSON.stringify(obj, (_key, value) => |
| 70 | + value === undefined ? null : value |
| 71 | + ); |
| 72 | + } |
91 | 73 |
|
92 | | - if(page in eel._start_geometry.pages) { |
93 | | - size = eel._start_geometry.pages[page].size; |
94 | | - position = eel._start_geometry.pages[page].position; |
| 74 | + #call_return(call) { |
| 75 | + return (callback = null) => { |
| 76 | + if (callback !== null) |
| 77 | + this.#call_return_callbacks[call.call] = {resolve: callback}; |
| 78 | + else |
| 79 | + return new Promise((resolve, reject) => |
| 80 | + this.#call_return_callbacks[call.call] = {resolve, reject} |
| 81 | + ); |
95 | 82 | } |
| 83 | + } |
96 | 84 |
|
97 | | - if(size != null){ |
98 | | - window.resizeTo(size[0], size[1]); |
| 85 | + #position_window(page) { |
| 86 | + let size = this.#start_geometry['default'].size; |
| 87 | + let position = this.#start_geometry['default'].position; |
| 88 | + if (page in this.#start_geometry.pages) { |
| 89 | + size = this.#start_geometry.pages[page].size; |
| 90 | + position = this.#start_geometry.pages[page].position; |
99 | 91 | } |
100 | | - |
101 | | - if(position != null){ |
| 92 | + if (size !== null) |
| 93 | + window.resizeTo(size[0], size[1]); |
| 94 | + if (position !== null) |
102 | 95 | window.moveTo(position[0], position[1]); |
103 | | - } |
104 | | - }, |
| 96 | + } |
105 | 97 |
|
106 | | - _init: function() { |
107 | | - eel._mock_py_functions(); |
| 98 | + #websocket; |
108 | 99 |
|
109 | | - document.addEventListener("DOMContentLoaded", function(event) { |
110 | | - let page = window.location.pathname.substring(1); |
111 | | - eel._position_window(page); |
| 100 | + #init() { |
| 101 | + this.#mock_py_functions(); |
112 | 102 |
|
113 | | - let websocket_addr = (eel._host + '/eel').replace('http', 'ws'); |
114 | | - websocket_addr += ('?page=' + page); |
115 | | - eel._websocket = new WebSocket(websocket_addr); |
| 103 | + document.addEventListener("DOMContentLoaded", (_event) => { |
| 104 | + const page = window.location.pathname.substring(1); |
| 105 | + this.#position_window(page); |
116 | 106 |
|
117 | | - eel._websocket.onopen = function() { |
118 | | - for(let i = 0; i < eel._py_functions.length; i++){ |
119 | | - let py_function = eel._py_functions[i]; |
120 | | - eel._import_py_function(py_function); |
121 | | - } |
| 107 | + const websocket_addr = |
| 108 | + (this.#host + '/eel').replace('http', 'ws') + ('?page=' + page); |
| 109 | + this.#websocket = new WebSocket(websocket_addr); |
122 | 110 |
|
123 | | - while(eel._mock_queue.length > 0) { |
124 | | - let call = eel._mock_queue.shift(); |
125 | | - eel._websocket.send(eel._toJSON(call)); |
| 111 | + this.#websocket.onopen = () => { |
| 112 | + for (let i = 0; i < this.#py_functions.length; i++) { |
| 113 | + const py_function = this.#py_functions[i]; |
| 114 | + this.#import_py_function(py_function); |
| 115 | + } |
| 116 | + while (this.#mock_queue.length > 0) { |
| 117 | + const call = this.#mock_queue.shift(); |
| 118 | + this.#websocket.send(this.#to_json(call)); |
126 | 119 | } |
127 | 120 | }; |
128 | 121 |
|
129 | | - eel._websocket.onmessage = function (e) { |
130 | | - let message = JSON.parse(e.data); |
131 | | - if(message.hasOwnProperty('call') ) { |
132 | | - // Python making a function call into us |
133 | | - if(message.name in eel._exposed_functions) { |
| 122 | + this.#websocket.onmessage = (event) => { |
| 123 | + const msg = JSON.parse(event.data); |
| 124 | + if (msg.hasOwnProperty('call')) { |
| 125 | + if (msg.name in this.#exposed_functions) { |
| 126 | + // Python making a function call into us |
134 | 127 | try { |
135 | | - let return_val = eel._exposed_functions[message.name](...message.args); |
136 | | - eel._websocket.send(eel._toJSON({'return': message.call, 'status':'ok', 'value': return_val})); |
137 | | - } catch(err) { |
138 | | - debugger |
139 | | - eel._websocket.send(eel._toJSON( |
140 | | - {'return': message.call, |
141 | | - 'status':'error', |
142 | | - 'error': err.message, |
143 | | - 'stack': err.stack})); |
| 128 | + const returned_value = |
| 129 | + this.#exposed_functions[msg.name](...msg.args); |
| 130 | + this.#websocket.send(this.#to_json({ |
| 131 | + 'return': msg.call, |
| 132 | + 'status': 'ok', |
| 133 | + 'value': returned_value |
| 134 | + })); |
| 135 | + } catch (error) { |
| 136 | + this.#websocket.send(this.#to_json({ |
| 137 | + 'return': msg.call, |
| 138 | + 'status': 'error', |
| 139 | + 'error': error.message, |
| 140 | + 'stack': error.stack |
| 141 | + })); |
144 | 142 | } |
145 | 143 | } |
146 | | - } else if(message.hasOwnProperty('return')) { |
| 144 | + } else |
| 145 | + if (msg.hasOwnProperty('return')) |
147 | 146 | // Python returning a value to us |
148 | | - if(message['return'] in eel._call_return_callbacks) { |
149 | | - if(message['status']==='ok'){ |
150 | | - eel._call_return_callbacks[message['return']].resolve(message.value); |
151 | | - delete eel._call_return_callbacks[message['return']]; |
152 | | - } |
153 | | - else if(message['status']==='error' && eel._call_return_callbacks[message['return']].reject) { |
154 | | - eel._call_return_callbacks[message['return']].reject(message['error']); |
155 | | - delete eel._call_return_callbacks[message['return']]; |
156 | | - } |
| 147 | + if (msg['return'] in this.#call_return_callbacks) { |
| 148 | + const callback = |
| 149 | + this.#call_return_callbacks[msg['return']]; |
| 150 | + const status = msg['status']; |
| 151 | + if (status === 'ok') |
| 152 | + callback.resolve(msg.value); |
| 153 | + else |
| 154 | + if (status === 'error' && callback.reject) |
| 155 | + callback.reject(msg['error']); |
| 156 | + delete this.#call_return_callbacks[msg['return']]; |
157 | 157 | } |
158 | | - } else { |
159 | | - throw 'Invalid message ' + message; |
160 | | - } |
161 | | - |
| 158 | + else |
| 159 | + throw 'Invalid message ' + msg; |
162 | 160 | }; |
163 | 161 | }); |
164 | 162 | } |
165 | | -}; |
| 163 | +} |
166 | 164 |
|
167 | | -eel._init(); |
| 165 | +const eel = new Eel(); |
168 | 166 |
|
169 | | -if(typeof require !== 'undefined'){ |
| 167 | +if (typeof require !== 'undefined') { |
170 | 168 | // Avoid name collisions when using Electron, so jQuery etc work normally |
171 | 169 | window.nodeRequire = require; |
172 | 170 | delete window.require; |
|
0 commit comments