Skip to content

Commit fc0c867

Browse files
committed
Bridge - Get Bind List After Token
* Get Bind List After Token * Renaming bridge files
1 parent 3f683ea commit fc0c867

File tree

7 files changed

+1131
-1116
lines changed

7 files changed

+1131
-1116
lines changed

bridge/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# WebUI Bridge
22

3-
The WebUI Bridge connects the UI (_Web Browser_) with the backend application through WebSocket. This bridge is written in TypeScript, and it needs to be transpiled to JavaScript using [ESBuild](https://esbuild.github.io/) to produce `webui_bridge.js`, then converted to C header using the Python script `js2c.py` to generate `webui_bridge.h`.
3+
The WebUI Bridge connects the UI (_Web Browser_) with the backend application through WebSocket. This bridge is written in TypeScript, and it needs to be transpiled to JavaScript using [ESBuild](https://esbuild.github.io/) to produce `webui.js`, then converted to C header using the Python script `js2c.py` to generate `webui_bridge.h`.
44

55
### Windows
66

77
- Install [Python](https://www.python.org/downloads/)
88
- Install [Node.js](https://nodejs.org/en/download)
99
- cd `webui\bridge`
1010
- `npm install esbuild`
11-
- `.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=.\ .\webui_bridge.ts`
11+
- `.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=.\ .\webui.ts`
1212
- `python js2c.py`
1313

1414
### Windows PowerShell
@@ -24,7 +24,7 @@ The WebUI Bridge connects the UI (_Web Browser_) with the backend application th
2424
- Install [Node.js](https://nodejs.org/en/download)
2525
- cd `webui/bridge`
2626
- `npm install esbuild`
27-
- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui_bridge.ts`
27+
- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui.ts`
2828
- `python js2c.py`
2929

3030
### Linux Bash
@@ -38,7 +38,7 @@ The WebUI Bridge connects the UI (_Web Browser_) with the backend application th
3838
- Install [Node.js](https://nodejs.org/en/download)
3939
- cd `webui/bridge`
4040
- `npm install esbuild`
41-
- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui_bridge.ts`
41+
- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui.ts`
4242
- `python js2c.py`
4343

4444
### macOS Bash

bridge/build.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ IF NOT EXIST "%project_root%\bridge\node_modules\esbuild\" (
3737

3838
REM Transpile WebUI-Bridge (TS to JS) & Convert WebUI-Bridge (JS to C)
3939
echo Transpile and bundle WebUI-Bridge from TypeScript to JavaScript...
40-
.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui_bridge.ts & %python_cmd% js2c.py
40+
.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui.ts & %python_cmd% js2c.py
4141

4242
echo Done.
4343
cd %cd%

bridge/build.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ if (-not (Test-Path "$project_root\bridge\node_modules\esbuild")) {
5959

6060
# Transpile WebUI-Bridge (TS to JS)
6161
if (!$silent) { Write-Host "Transpile and bundle WebUI-Bridge from TypeScript to JavaScript..." }
62-
.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui_bridge.ts $log_level
62+
.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui.ts $log_level
6363

6464
# Convert WebUI-Bridge (JS to C)
6565
if (!$silent) { Write-Host "Convert WebUI-Bridge JavaScript to C Header..." }

bridge/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ done
2828
if [ "$silent" = true ]; then log_level=--log-level=warning; fi
2929

3030
if [ "$silent" != true ]; then echo "Transpile and bundle TS sources to webui.js"; fi
31-
esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui_bridge.ts $log_level
31+
esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui.ts $log_level
3232

3333
if [ "$silent" != true ]; then echo "Convert JS source to C header"; fi
3434
python3 js2c.py

bridge/js2c.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ def js_to_c_header(input_filename, output_filename):
4141
return
4242

4343
# Main
44-
js_to_c_header('webui_bridge.js', 'webui_bridge.h')
44+
js_to_c_header('webui.js', 'webui_bridge.h')
Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class WebuiBridge {
2424
#secure: boolean;
2525
#token: number;
2626
#port: number;
27-
#bindList: string[] = [];
2827
#log: boolean;
2928
#winX: number;
3029
#winY: number;
@@ -38,12 +37,13 @@ class WebuiBridge {
3837
#TokenAccepted: boolean = false;
3938
#closeReason: number = 0;
4039
#closeValue: string;
41-
#hasEvents: boolean = false;
40+
#AllEvents: boolean = false;
4241
#callPromiseID: Uint16Array = new Uint16Array(1);
4342
#callPromiseResolve: (((data: string) => unknown) | undefined)[] = [];
4443
#allowNavigation: boolean = true;
4544
#sendQueue: Uint8Array[] = [];
4645
#isSending: boolean = false;
46+
#bindsList: string[];
4747
// WebUI Const
4848
#WEBUI_SIGNATURE: number = 221;
4949
#CMD_JS: number = 254;
@@ -74,20 +74,18 @@ class WebuiBridge {
7474
};
7575
// Constructor
7676
constructor({
77-
secure,
78-
token,
79-
port,
80-
bindList,
77+
secure = false,
78+
token = 0,
79+
port = 0,
8180
log = false,
82-
winX,
83-
winY,
84-
winW,
85-
winH,
81+
winX = 0,
82+
winY = 0,
83+
winW = 0,
84+
winH = 0,
8685
}: {
8786
secure: boolean;
8887
token: number;
8988
port: number;
90-
bindList: string[];
9189
log?: boolean;
9290
winX: number;
9391
winY: number;
@@ -98,7 +96,6 @@ class WebuiBridge {
9896
this.#secure = secure;
9997
this.#token = token;
10098
this.#port = port;
101-
this.#bindList = bindList;
10299
this.#log = log;
103100
this.#winX = winX;
104101
this.#winY = winY;
@@ -129,7 +126,7 @@ class WebuiBridge {
129126
if ('navigation' in globalThis) {
130127
globalThis.navigation.addEventListener('navigate', (event) => {
131128
if (!this.#allowNavigation) {
132-
if (this.#hasEvents && (this.#wsIsConnected())) {
129+
if (this.#AllEvents && (this.#wsIsConnected())) {
133130
event.preventDefault();
134131
const url = new URL(event.destination.url);
135132
if (this.#log) console.log(`WebUI -> DOM -> Navigation Event [${url.href}]`);
@@ -141,7 +138,7 @@ class WebuiBridge {
141138
// Click navigation event listener
142139
addRefreshableEventListener(document.body, 'a', 'click', (event) => {
143140
if (!this.#allowNavigation) {
144-
if (this.#hasEvents && (this.#wsIsConnected())) {
141+
if (this.#AllEvents && (this.#wsIsConnected())) {
145142
event.preventDefault();
146143
const { href } = event.target as HTMLAnchorElement;
147144
if (this.#log) console.log(`WebUI -> DOM -> Navigation Click Event [${href}]`);
@@ -229,13 +226,8 @@ class WebuiBridge {
229226
buffer[index + 1] = (value >>> 8) & 0xff; // Most significant byte
230227
}
231228
#start() {
232-
this.#generateCallObjects();
233229
this.#keepAlive();
234230
this.#callPromiseID[0] = 0;
235-
if (this.#bindList.includes('')) {
236-
this.#hasEvents = true;
237-
this.#allowNavigation = false;
238-
}
239231
// Connect to the backend application
240232
this.#wsConnect();
241233
}
@@ -257,9 +249,9 @@ class WebuiBridge {
257249
if (/^on(click)/.test(key)) {
258250
globalThis.addEventListener(key.slice(2), (event) => {
259251
if (!(event.target instanceof HTMLElement)) return;
260-
if (
261-
this.#hasEvents ||
262-
(event.target.id !== '' && this.#bindList.includes(event.target?.id))
252+
if (this.#AllEvents ||
253+
((event.target.id !== '') &&
254+
(this.#bindsList.includes(event.target?.id)))
263255
) {
264256
this.#sendClick(event.target.id);
265257
}
@@ -371,16 +363,6 @@ class WebuiBridge {
371363
// this.#addID(packet, 0, this.#PROTOCOL_ID)
372364
this.#sendData(packet);
373365
if (this.#log) console.log(`WebUI -> Send Token [0x${this.#token.toString(16).padStart(8, '0')}]`);
374-
// Refresh the page if token not accepted
375-
setTimeout(() => this.#checkTokenReload(), 1000);
376-
}
377-
}
378-
#checkTokenReload() {
379-
if (!this.#TokenAccepted) {
380-
if (this.#log) console.log(`WebUI -> Token [0x${this.#token.toString(16).padStart(8, '0')}] not accepted. Reload page...`);
381-
this.#allowNavigation = true;
382-
this.#wsStayAlive = false;
383-
globalThis.location.reload();
384366
}
385367
}
386368
#sendEventNavigation(url: string) {
@@ -415,11 +397,19 @@ class WebuiBridge {
415397
globalThis.close();
416398
}, 1000);
417399
}
400+
#updateBindsList() {
401+
if (this.#bindsList.includes('')) {
402+
this.#AllEvents = true;
403+
this.#allowNavigation = false;
404+
}
405+
this.#generateCallObjects();
406+
this.#clicksListener();
407+
}
418408
#toUint16(value: number): number {
419409
return value & 0xffff;
420410
}
421411
#generateCallObjects() {
422-
for (const bind of this.#bindList) {
412+
for (const bind of this.#bindsList) {
423413
if (bind.trim()) {
424414
const fn = bind;
425415
if (fn.trim()) {
@@ -519,7 +509,6 @@ class WebuiBridge {
519509
this.#unfreezeUI();
520510
if (this.#log) console.log('WebUI -> Connected');
521511
this.#checkToken();
522-
this.#clicksListener();
523512
};
524513
#wsOnError = (event: Event) => {
525514
if (this.#log) console.log(`WebUI -> Connection failed.`);
@@ -571,7 +560,7 @@ class WebuiBridge {
571560
// 2: [ID]
572561
// 3: [CMD]
573562
// 4: [Script]
574-
const script = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
563+
const script: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
575564
const scriptSanitize = script.replace(/(?:\r\n|\r|\n)/g, '\n');
576565
if (this.#log) console.log(`WebUI -> CMD -> JS [${scriptSanitize}]`);
577566
// Get callback result
@@ -638,7 +627,7 @@ class WebuiBridge {
638627
// 2: [ID]
639628
// 3: [CMD]
640629
// 4: [Call Response]
641-
const callResponse = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
630+
const callResponse: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
642631
if (this.#log) {
643632
console.log(`WebUI -> CMD -> Call Response [${callResponse}]`);
644633
}
@@ -658,7 +647,7 @@ class WebuiBridge {
658647
// 2: [ID]
659648
// 3: [CMD]
660649
// 4: [URL]
661-
const url = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
650+
const url: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
662651
console.log(`WebUI -> CMD -> Navigation [${url}]`);
663652
this.#close(this.#CMD_NAVIGATION, url);
664653
break;
@@ -669,9 +658,11 @@ class WebuiBridge {
669658
// 2: [ID]
670659
// 3: [CMD]
671660
// 4: [New Element]
672-
const newElement = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
661+
const newElement: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
673662
console.log(`WebUI -> CMD -> New Bind ID [${newElement}]`);
674-
if (!this.#bindList.includes(newElement)) this.#bindList.push(newElement);
663+
if (!this.#bindsList.includes(newElement)) this.#bindsList.push(newElement);
664+
// Generate objects
665+
this.#updateBindsList();
675666
break;
676667
case this.#CMD_CLOSE:
677668
// Protocol
@@ -699,16 +690,29 @@ class WebuiBridge {
699690
// 2: [ID]
700691
// 3: [CMD]
701692
// 4: [Status]
693+
// 5: [BindsList]
702694
const status = (buffer8[this.#PROTOCOL_DATA] == 0 ? false : true);
695+
const tokenHex = `0x${this.#token.toString(16).padStart(8, '0')}`;
703696
if (status) {
704-
if (this.#log) console.log(`WebUI -> CMD -> Token Accepted`);
697+
if (this.#log) console.log(`WebUI -> CMD -> Token [${tokenHex}] Accepted`);
705698
this.#TokenAccepted = true;
699+
// Get binds list (CSV)
700+
let csv: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA + 1);
701+
csv = csv.endsWith(',') ? csv.slice(0, -1) : csv;
702+
this.#bindsList = csv.split(',');
703+
// Generate objects
704+
this.#updateBindsList();
705+
// User event callback
706706
if (this.#eventsCallback) {
707707
this.#eventsCallback(this.event.CONNECTED);
708708
}
709709
}
710710
else {
711-
if (this.#log) console.log(`WebUI -> CMD -> Token Not Accepted`);
711+
if (this.#log) console.log(`WebUI -> CMD -> Token [${tokenHex}] Not Accepted. Reload page...`);
712+
// Refresh the page to get a new token
713+
this.#allowNavigation = true;
714+
this.#wsStayAlive = false;
715+
globalThis.location.reload();
712716
}
713717
break;
714718
}
@@ -751,7 +755,7 @@ class WebuiBridge {
751755
if (!this.#wsIsConnected()) return Promise.reject(new Error('WebSocket is not connected'));
752756

753757
// Check binding list
754-
if (!this.#hasEvents && !this.#bindList.includes(`${fn}`))
758+
if (!this.#AllEvents && !this.#bindsList.includes(`${fn}`))
755759
return Promise.reject(new ReferenceError(`No binding was found for "${fn}"`));
756760

757761
// Call backend and wait for response

0 commit comments

Comments
 (0)