@flighthq/host-web 0.4.0-edge.1908.751021c
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/dist/contract.d.ts +32 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +32 -0
- package/dist/contract.js.map +1 -0
- package/dist/enableHostWeb.d.ts +2 -0
- package/dist/enableHostWeb.d.ts.map +1 -0
- package/dist/enableHostWeb.js +47 -0
- package/dist/enableHostWeb.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/webAccessibility.d.ts +3 -0
- package/dist/webAccessibility.d.ts.map +1 -0
- package/dist/webAccessibility.js +12 -0
- package/dist/webAccessibility.js.map +1 -0
- package/dist/webApp.d.ts +3 -0
- package/dist/webApp.d.ts.map +1 -0
- package/dist/webApp.js +156 -0
- package/dist/webApp.js.map +1 -0
- package/dist/webClipboard.d.ts +3 -0
- package/dist/webClipboard.d.ts.map +1 -0
- package/dist/webClipboard.js +132 -0
- package/dist/webClipboard.js.map +1 -0
- package/dist/webConnectivity.d.ts +3 -0
- package/dist/webConnectivity.d.ts.map +1 -0
- package/dist/webConnectivity.js +58 -0
- package/dist/webConnectivity.js.map +1 -0
- package/dist/webCursor.d.ts +3 -0
- package/dist/webCursor.d.ts.map +1 -0
- package/dist/webCursor.js +8 -0
- package/dist/webCursor.js.map +1 -0
- package/dist/webDevice.d.ts +3 -0
- package/dist/webDevice.d.ts.map +1 -0
- package/dist/webDevice.js +12 -0
- package/dist/webDevice.js.map +1 -0
- package/dist/webDialog.d.ts +3 -0
- package/dist/webDialog.d.ts.map +1 -0
- package/dist/webDialog.js +47 -0
- package/dist/webDialog.js.map +1 -0
- package/dist/webFilesystem.d.ts +3 -0
- package/dist/webFilesystem.d.ts.map +1 -0
- package/dist/webFilesystem.js +12 -0
- package/dist/webFilesystem.js.map +1 -0
- package/dist/webGeolocation.d.ts +3 -0
- package/dist/webGeolocation.d.ts.map +1 -0
- package/dist/webGeolocation.js +58 -0
- package/dist/webGeolocation.js.map +1 -0
- package/dist/webGlyphRasterizer.d.ts +5 -0
- package/dist/webGlyphRasterizer.d.ts.map +1 -0
- package/dist/webGlyphRasterizer.js +101 -0
- package/dist/webGlyphRasterizer.js.map +1 -0
- package/dist/webHaptics.d.ts +3 -0
- package/dist/webHaptics.d.ts.map +1 -0
- package/dist/webHaptics.js +12 -0
- package/dist/webHaptics.js.map +1 -0
- package/dist/webImage.d.ts +3 -0
- package/dist/webImage.d.ts.map +1 -0
- package/dist/webImage.js +26 -0
- package/dist/webImage.js.map +1 -0
- package/dist/webKeyboard.d.ts +3 -0
- package/dist/webKeyboard.d.ts.map +1 -0
- package/dist/webKeyboard.js +12 -0
- package/dist/webKeyboard.js.map +1 -0
- package/dist/webLifecycle.d.ts +3 -0
- package/dist/webLifecycle.d.ts.map +1 -0
- package/dist/webLifecycle.js +12 -0
- package/dist/webLifecycle.js.map +1 -0
- package/dist/webLoop.d.ts +3 -0
- package/dist/webLoop.d.ts.map +1 -0
- package/dist/webLoop.js +38 -0
- package/dist/webLoop.js.map +1 -0
- package/dist/webMediasession.d.ts +3 -0
- package/dist/webMediasession.d.ts.map +1 -0
- package/dist/webMediasession.js +51 -0
- package/dist/webMediasession.js.map +1 -0
- package/dist/webMenu.d.ts +3 -0
- package/dist/webMenu.d.ts.map +1 -0
- package/dist/webMenu.js +31 -0
- package/dist/webMenu.js.map +1 -0
- package/dist/webNotification.d.ts +3 -0
- package/dist/webNotification.d.ts.map +1 -0
- package/dist/webNotification.js +85 -0
- package/dist/webNotification.js.map +1 -0
- package/dist/webPermissions.d.ts +3 -0
- package/dist/webPermissions.d.ts.map +1 -0
- package/dist/webPermissions.js +37 -0
- package/dist/webPermissions.js.map +1 -0
- package/dist/webPlatform.d.ts +3 -0
- package/dist/webPlatform.d.ts.map +1 -0
- package/dist/webPlatform.js +12 -0
- package/dist/webPlatform.js.map +1 -0
- package/dist/webPower.d.ts +3 -0
- package/dist/webPower.d.ts.map +1 -0
- package/dist/webPower.js +217 -0
- package/dist/webPower.js.map +1 -0
- package/dist/webProtocol.d.ts +3 -0
- package/dist/webProtocol.d.ts.map +1 -0
- package/dist/webProtocol.js +78 -0
- package/dist/webProtocol.js.map +1 -0
- package/dist/webScreen.d.ts +3 -0
- package/dist/webScreen.d.ts.map +1 -0
- package/dist/webScreen.js +12 -0
- package/dist/webScreen.js.map +1 -0
- package/dist/webSensors.d.ts +3 -0
- package/dist/webSensors.d.ts.map +1 -0
- package/dist/webSensors.js +12 -0
- package/dist/webSensors.js.map +1 -0
- package/dist/webShare.d.ts +3 -0
- package/dist/webShare.d.ts.map +1 -0
- package/dist/webShare.js +33 -0
- package/dist/webShare.js.map +1 -0
- package/dist/webShell.d.ts +3 -0
- package/dist/webShell.d.ts.map +1 -0
- package/dist/webShell.js +51 -0
- package/dist/webShell.js.map +1 -0
- package/dist/webStatusbar.d.ts +3 -0
- package/dist/webStatusbar.d.ts.map +1 -0
- package/dist/webStatusbar.js +52 -0
- package/dist/webStatusbar.js.map +1 -0
- package/dist/webStorage.d.ts +3 -0
- package/dist/webStorage.d.ts.map +1 -0
- package/dist/webStorage.js +12 -0
- package/dist/webStorage.js.map +1 -0
- package/dist/webWebcam.d.ts +3 -0
- package/dist/webWebcam.d.ts.map +1 -0
- package/dist/webWebcam.js +12 -0
- package/dist/webWebcam.js.map +1 -0
- package/dist/webWindow.d.ts +3 -0
- package/dist/webWindow.d.ts.map +1 -0
- package/dist/webWindow.js +135 -0
- package/dist/webWindow.js.map +1 -0
- package/package.json +76 -0
- package/src/enableHostWeb.test.ts +12 -0
- package/src/evidence.test.ts +172 -0
- package/src/webAccessibility.test.ts +22 -0
- package/src/webApp.test.ts +22 -0
- package/src/webClipboard.test.ts +22 -0
- package/src/webConnectivity.test.ts +22 -0
- package/src/webCursor.test.ts +26 -0
- package/src/webDevice.test.ts +22 -0
- package/src/webDialog.test.ts +22 -0
- package/src/webFilesystem.test.ts +22 -0
- package/src/webGeolocation.test.ts +22 -0
- package/src/webGlyphRasterizer.test.ts +153 -0
- package/src/webHaptics.test.ts +22 -0
- package/src/webImage.test.ts +22 -0
- package/src/webKeyboard.test.ts +22 -0
- package/src/webLifecycle.test.ts +22 -0
- package/src/webLoop.test.ts +123 -0
- package/src/webMediasession.test.ts +22 -0
- package/src/webMenu.test.ts +22 -0
- package/src/webNotification.test.ts +22 -0
- package/src/webPermissions.test.ts +22 -0
- package/src/webPlatform.test.ts +22 -0
- package/src/webPower.test.ts +22 -0
- package/src/webProtocol.test.ts +22 -0
- package/src/webScreen.test.ts +22 -0
- package/src/webSensors.test.ts +22 -0
- package/src/webShare.test.ts +22 -0
- package/src/webShell.test.ts +22 -0
- package/src/webStatusbar.test.ts +22 -0
- package/src/webStorage.test.ts +22 -0
- package/src/webWebcam.test.ts +22 -0
- package/src/webWindow.test.ts +22 -0
package/dist/webShell.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { installShellHostBackend, observeShellHostResult } from '@flighthq/shell/contract';
|
|
2
|
+
export function enableHostWebShell() {
|
|
3
|
+
if (_enabled)
|
|
4
|
+
return;
|
|
5
|
+
_enabled = true;
|
|
6
|
+
const backend = {
|
|
7
|
+
beep() { },
|
|
8
|
+
async moveItemsToTrash() {
|
|
9
|
+
return [];
|
|
10
|
+
},
|
|
11
|
+
async moveToTrash() {
|
|
12
|
+
return false;
|
|
13
|
+
},
|
|
14
|
+
async openExternal(url) {
|
|
15
|
+
if (typeof window === 'undefined' || typeof window.open !== 'function') {
|
|
16
|
+
observeShellHostResult('openExternal', false);
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const result = window.open(url, '_blank', 'noopener') !== null;
|
|
21
|
+
observeShellHostResult('openExternal', result);
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
observeShellHostResult('openExternal', false);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
async openPath() {
|
|
30
|
+
return false;
|
|
31
|
+
},
|
|
32
|
+
async openPathResult() {
|
|
33
|
+
return 'unavailable on web';
|
|
34
|
+
},
|
|
35
|
+
async readShortcutLink() {
|
|
36
|
+
return null;
|
|
37
|
+
},
|
|
38
|
+
async showItemInFolder() {
|
|
39
|
+
return false;
|
|
40
|
+
},
|
|
41
|
+
async writeShortcutLink() {
|
|
42
|
+
return false;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
installShellHostBackend(backend);
|
|
46
|
+
}
|
|
47
|
+
export function resetHostWebShellForTest() {
|
|
48
|
+
_enabled = false;
|
|
49
|
+
}
|
|
50
|
+
let _enabled = false;
|
|
51
|
+
//# sourceMappingURL=webShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webShell.js","sourceRoot":"","sources":["../src/webShell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAG3F,MAAM,UAAU,kBAAkB;IAChC,IAAI,QAAQ;QAAE,OAAO;IACrB,QAAQ,GAAG,IAAI,CAAC;IAChB,MAAM,OAAO,GAAiB;QAC5B,IAAI,KAAI,CAAC;QACT,KAAK,CAAC,gBAAgB;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK,CAAC,WAAW;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,CAAC,YAAY,CAAC,GAAG;YACpB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACvE,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;gBAC/D,sBAAsB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;gBAC/C,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,KAAK,CAAC,QAAQ;YACZ,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,CAAC,cAAc;YAClB,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,gBAAgB;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,gBAAgB;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,CAAC,iBAAiB;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;IACF,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,IAAI,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webStatusbar.d.ts","sourceRoot":"","sources":["../src/webStatusbar.ts"],"names":[],"mappings":"AAOA,wBAAgB,sBAAsB,IAAI,IAAI,CA2C7C;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { installStatusBarHostBackend, observeStatusBarHostResult, packedRgbaToHexColor, } from '@flighthq/statusbar/contract';
|
|
2
|
+
export function enableHostWebStatusBar() {
|
|
3
|
+
if (_enabled)
|
|
4
|
+
return;
|
|
5
|
+
_enabled = true;
|
|
6
|
+
const backend = {
|
|
7
|
+
getInfo(out) {
|
|
8
|
+
out.color = 0;
|
|
9
|
+
out.height = -1;
|
|
10
|
+
out.overlaysContent = false;
|
|
11
|
+
out.style = 'default';
|
|
12
|
+
out.visible = true;
|
|
13
|
+
return out;
|
|
14
|
+
},
|
|
15
|
+
setBackgroundColor(color) {
|
|
16
|
+
try {
|
|
17
|
+
if (typeof document === 'undefined') {
|
|
18
|
+
observeStatusBarHostResult('setBackgroundColor', false);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const head = document.head;
|
|
22
|
+
if (head === null || head === undefined) {
|
|
23
|
+
observeStatusBarHostResult('setBackgroundColor', false);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let meta = head.querySelector('meta[name="theme-color"]');
|
|
27
|
+
if (meta === null) {
|
|
28
|
+
meta = document.createElement('meta');
|
|
29
|
+
meta.setAttribute('name', 'theme-color');
|
|
30
|
+
head.appendChild(meta);
|
|
31
|
+
}
|
|
32
|
+
meta.setAttribute('content', packedRgbaToHexColor(color));
|
|
33
|
+
observeStatusBarHostResult('setBackgroundColor', true);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
observeStatusBarHostResult('setBackgroundColor', false);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
setOverlaysContent() { },
|
|
40
|
+
setStyle() { },
|
|
41
|
+
setVisible() { },
|
|
42
|
+
subscribe() {
|
|
43
|
+
return () => { };
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
installStatusBarHostBackend(backend);
|
|
47
|
+
}
|
|
48
|
+
export function resetHostWebStatusBarForTest() {
|
|
49
|
+
_enabled = false;
|
|
50
|
+
}
|
|
51
|
+
let _enabled = false;
|
|
52
|
+
//# sourceMappingURL=webStatusbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webStatusbar.js","sourceRoot":"","sources":["../src/webStatusbar.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,UAAU,sBAAsB;IACpC,IAAI,QAAQ;QAAE,OAAO;IACrB,QAAQ,GAAG,IAAI,CAAC;IAChB,MAAM,OAAO,GAAqB;QAChC,OAAO,CAAC,GAAkB;YACxB,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;YACd,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAChB,GAAG,CAAC,eAAe,GAAG,KAAK,CAAC;YAC5B,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;YACtB,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;YACnB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,kBAAkB,CAAC,KAAa;YAC9B,IAAI,CAAC;gBACH,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;oBACpC,0BAA0B,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;gBAC3B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;oBACxC,0BAA0B,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBACD,IAAI,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAC;gBAC1D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;oBAClB,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;oBACtC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;oBACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC1D,0BAA0B,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACP,0BAA0B,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,kBAAkB,KAAU,CAAC;QAC7B,QAAQ,KAAU,CAAC;QACnB,UAAU,KAAU,CAAC;QACrB,SAAS;YACP,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;IACF,2BAA2B,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,IAAI,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webStorage.d.ts","sourceRoot":"","sources":["../src/webStorage.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createWebStorageBackend, installStorageHostBackend } from '@flighthq/storage/contract';
|
|
2
|
+
export function enableHostWebStorage() {
|
|
3
|
+
if (_enabled)
|
|
4
|
+
return;
|
|
5
|
+
_enabled = true;
|
|
6
|
+
installStorageHostBackend(createWebStorageBackend());
|
|
7
|
+
}
|
|
8
|
+
export function resetHostWebStorageForTest() {
|
|
9
|
+
_enabled = false;
|
|
10
|
+
}
|
|
11
|
+
let _enabled = false;
|
|
12
|
+
//# sourceMappingURL=webStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webStorage.js","sourceRoot":"","sources":["../src/webStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEhG,MAAM,UAAU,oBAAoB;IAClC,IAAI,QAAQ;QAAE,OAAO;IACrB,QAAQ,GAAG,IAAI,CAAC;IAChB,yBAAyB,CAAC,uBAAuB,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,IAAI,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWebcam.d.ts","sourceRoot":"","sources":["../src/webWebcam.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createWebWebcamBackend, installWebcamHostBackend } from '@flighthq/webcam/contract';
|
|
2
|
+
export function enableHostWebWebcam() {
|
|
3
|
+
if (_enabled)
|
|
4
|
+
return;
|
|
5
|
+
_enabled = true;
|
|
6
|
+
installWebcamHostBackend(createWebWebcamBackend());
|
|
7
|
+
}
|
|
8
|
+
export function resetHostWebWebcamForTest() {
|
|
9
|
+
_enabled = false;
|
|
10
|
+
}
|
|
11
|
+
let _enabled = false;
|
|
12
|
+
//# sourceMappingURL=webWebcam.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWebcam.js","sourceRoot":"","sources":["../src/webWebcam.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAE7F,MAAM,UAAU,mBAAmB;IACjC,IAAI,QAAQ;QAAE,OAAO;IACrB,QAAQ,GAAG,IAAI,CAAC;IAChB,wBAAwB,CAAC,sBAAsB,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,IAAI,QAAQ,GAAG,KAAK,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWindow.d.ts","sourceRoot":"","sources":["../src/webWindow.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,IAAI,IAAI,CAwH1C;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { installWindowHostBackend, observeWindowHostResult } from '@flighthq/application/contract';
|
|
2
|
+
export function enableHostWebWindow() {
|
|
3
|
+
if (_enabled)
|
|
4
|
+
return;
|
|
5
|
+
_enabled = true;
|
|
6
|
+
const backend = {
|
|
7
|
+
center(win) {
|
|
8
|
+
if (typeof window === 'undefined' || typeof window.moveTo !== 'function' || typeof screen === 'undefined')
|
|
9
|
+
return;
|
|
10
|
+
try {
|
|
11
|
+
window.moveTo(Math.round((screen.availWidth - win.width) / 2), Math.round((screen.availHeight - win.height) / 2));
|
|
12
|
+
observeWindowHostResult('center', true);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
observeWindowHostResult('center', false);
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
close() {
|
|
19
|
+
if (typeof window !== 'undefined' && typeof window.close === 'function') {
|
|
20
|
+
try {
|
|
21
|
+
window.close();
|
|
22
|
+
observeWindowHostResult('close', true);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
observeWindowHostResult('close', false);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
flashWindowFrame() { },
|
|
30
|
+
focus() {
|
|
31
|
+
if (typeof window !== 'undefined' && typeof window.focus === 'function') {
|
|
32
|
+
window.focus();
|
|
33
|
+
observeWindowHostResult('focus', true);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
getBounds(win, out) {
|
|
37
|
+
if (typeof window === 'undefined') {
|
|
38
|
+
out.x = win.x;
|
|
39
|
+
out.y = win.y;
|
|
40
|
+
out.width = win.width;
|
|
41
|
+
out.height = win.height;
|
|
42
|
+
observeWindowHostResult('getBounds', true);
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
out.x = window.screenX ?? win.x;
|
|
46
|
+
out.y = window.screenY ?? win.y;
|
|
47
|
+
out.width = window.innerWidth ?? win.width;
|
|
48
|
+
out.height = window.innerHeight ?? win.height;
|
|
49
|
+
observeWindowHostResult('getBounds', true);
|
|
50
|
+
return out;
|
|
51
|
+
},
|
|
52
|
+
hide() { },
|
|
53
|
+
maximize() { },
|
|
54
|
+
minimize() { },
|
|
55
|
+
open() {
|
|
56
|
+
const result = typeof window !== 'undefined';
|
|
57
|
+
observeWindowHostResult('open', result);
|
|
58
|
+
return result;
|
|
59
|
+
},
|
|
60
|
+
requestAttention() { },
|
|
61
|
+
restore() { },
|
|
62
|
+
setAlwaysOnTop() { },
|
|
63
|
+
setContentProtection() { },
|
|
64
|
+
setFullscreen(_win, fullscreen) {
|
|
65
|
+
if (typeof document === 'undefined')
|
|
66
|
+
return;
|
|
67
|
+
try {
|
|
68
|
+
if (fullscreen)
|
|
69
|
+
void document.documentElement.requestFullscreen?.();
|
|
70
|
+
else
|
|
71
|
+
void document.exitFullscreen?.();
|
|
72
|
+
observeWindowHostResult('setFullscreen', true);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
observeWindowHostResult('setFullscreen', false);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
setHasShadow() { },
|
|
79
|
+
setIcon(_win, icon) {
|
|
80
|
+
if (typeof document === 'undefined')
|
|
81
|
+
return;
|
|
82
|
+
let link = document.querySelector('link[rel="icon"]');
|
|
83
|
+
if (link === null) {
|
|
84
|
+
link = document.createElement('link');
|
|
85
|
+
link.rel = 'icon';
|
|
86
|
+
document.head.appendChild(link);
|
|
87
|
+
}
|
|
88
|
+
link.href = icon;
|
|
89
|
+
observeWindowHostResult('setIcon', true);
|
|
90
|
+
},
|
|
91
|
+
setMaximumSize() { },
|
|
92
|
+
setMenuBarVisible() { },
|
|
93
|
+
setMinimumSize() { },
|
|
94
|
+
setOpacity() { },
|
|
95
|
+
setParent() { },
|
|
96
|
+
setPosition(_win, x, y) {
|
|
97
|
+
if (typeof window !== 'undefined' && typeof window.moveTo === 'function') {
|
|
98
|
+
try {
|
|
99
|
+
window.moveTo(x, y);
|
|
100
|
+
observeWindowHostResult('setPosition', true);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
observeWindowHostResult('setPosition', false);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
setProgress() { },
|
|
108
|
+
setResizable() { },
|
|
109
|
+
setSize(_win, width, height) {
|
|
110
|
+
if (typeof window !== 'undefined' && typeof window.resizeTo === 'function') {
|
|
111
|
+
try {
|
|
112
|
+
window.resizeTo(width, height);
|
|
113
|
+
observeWindowHostResult('setSize', true);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
observeWindowHostResult('setSize', false);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
setSkipTaskbar() { },
|
|
121
|
+
setTitle(_win, title) {
|
|
122
|
+
if (typeof document !== 'undefined') {
|
|
123
|
+
document.title = title;
|
|
124
|
+
observeWindowHostResult('setTitle', true);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
show() { },
|
|
128
|
+
};
|
|
129
|
+
installWindowHostBackend(backend);
|
|
130
|
+
}
|
|
131
|
+
export function resetHostWebWindowForTest() {
|
|
132
|
+
_enabled = false;
|
|
133
|
+
}
|
|
134
|
+
let _enabled = false;
|
|
135
|
+
//# sourceMappingURL=webWindow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webWindow.js","sourceRoot":"","sources":["../src/webWindow.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flighthq/host-web",
|
|
3
|
+
"version": "0.4.0-edge.1908.751021c",
|
|
4
|
+
"author": "Joshua Granick and other contributors",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/flighthq/flight.git",
|
|
9
|
+
"directory": "packages/host-web"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./contract": {
|
|
20
|
+
"types": "./dist/contract.d.ts",
|
|
21
|
+
"default": "./dist/contract.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"src/**/*.test.ts",
|
|
27
|
+
"!dist/**/*.test.js",
|
|
28
|
+
"!dist/**/*.test.d.ts",
|
|
29
|
+
"!dist/**/*.test.js.map",
|
|
30
|
+
"!dist/**/*.test.d.ts.map"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc -b",
|
|
34
|
+
"clean": "tsc -b --clean",
|
|
35
|
+
"test": "vitest run --config vitest.config.ts",
|
|
36
|
+
"test:watch": "vitest --watch --config vitest.config.ts",
|
|
37
|
+
"prepack": "npm run clean && npm run clean:dist && npm run build",
|
|
38
|
+
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@flighthq/accessibility": "0.4.0-edge.1908.751021c",
|
|
42
|
+
"@flighthq/app": "0.4.0-edge.1908.751021c",
|
|
43
|
+
"@flighthq/application": "0.4.0-edge.1908.751021c",
|
|
44
|
+
"@flighthq/clipboard": "0.4.0-edge.1908.751021c",
|
|
45
|
+
"@flighthq/connectivity": "0.4.0-edge.1908.751021c",
|
|
46
|
+
"@flighthq/device": "0.4.0-edge.1908.751021c",
|
|
47
|
+
"@flighthq/dialog": "0.4.0-edge.1908.751021c",
|
|
48
|
+
"@flighthq/filesystem": "0.4.0-edge.1908.751021c",
|
|
49
|
+
"@flighthq/geolocation": "0.4.0-edge.1908.751021c",
|
|
50
|
+
"@flighthq/glyphatlas": "0.4.0-edge.1908.751021c",
|
|
51
|
+
"@flighthq/haptics": "0.4.0-edge.1908.751021c",
|
|
52
|
+
"@flighthq/image": "0.4.0-edge.1908.751021c",
|
|
53
|
+
"@flighthq/keyboard": "0.4.0-edge.1908.751021c",
|
|
54
|
+
"@flighthq/lifecycle": "0.4.0-edge.1908.751021c",
|
|
55
|
+
"@flighthq/mediasession": "0.4.0-edge.1908.751021c",
|
|
56
|
+
"@flighthq/menu": "0.4.0-edge.1908.751021c",
|
|
57
|
+
"@flighthq/notification": "0.4.0-edge.1908.751021c",
|
|
58
|
+
"@flighthq/permissions": "0.4.0-edge.1908.751021c",
|
|
59
|
+
"@flighthq/platform": "0.4.0-edge.1908.751021c",
|
|
60
|
+
"@flighthq/power": "0.4.0-edge.1908.751021c",
|
|
61
|
+
"@flighthq/protocol": "0.4.0-edge.1908.751021c",
|
|
62
|
+
"@flighthq/screen": "0.4.0-edge.1908.751021c",
|
|
63
|
+
"@flighthq/sensors": "0.4.0-edge.1908.751021c",
|
|
64
|
+
"@flighthq/share": "0.4.0-edge.1908.751021c",
|
|
65
|
+
"@flighthq/shell": "0.4.0-edge.1908.751021c",
|
|
66
|
+
"@flighthq/statusbar": "0.4.0-edge.1908.751021c",
|
|
67
|
+
"@flighthq/storage": "0.4.0-edge.1908.751021c",
|
|
68
|
+
"@flighthq/types": "0.4.0-edge.1908.751021c",
|
|
69
|
+
"@flighthq/webcam": "0.4.0-edge.1908.751021c"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"typescript": "^5.3.0"
|
|
73
|
+
},
|
|
74
|
+
"description": "Web host backend: installs browser-specific implementations of Flight capability seams (Canvas glyph rasterizer, DOM cursor)",
|
|
75
|
+
"sideEffects": false
|
|
76
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { enableHostWeb } from './enableHostWeb';
|
|
2
|
+
|
|
3
|
+
describe('enableHostWeb', () => {
|
|
4
|
+
it('does not throw on first call', () => {
|
|
5
|
+
expect(() => enableHostWeb()).not.toThrow();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
it('is idempotent', () => {
|
|
9
|
+
enableHostWeb();
|
|
10
|
+
expect(() => enableHostWeb()).not.toThrow();
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import type { OutputChunk, RollupOutput } from 'rollup';
|
|
4
|
+
import { build } from 'vite';
|
|
5
|
+
import { describe, expect, it } from 'vitest';
|
|
6
|
+
import { gzipSync } from 'zlib';
|
|
7
|
+
|
|
8
|
+
const ROOT = resolve(__dirname, '../../..');
|
|
9
|
+
const EVIDENCE_DIR = resolve(__dirname, '../evidence');
|
|
10
|
+
|
|
11
|
+
interface CapabilityEntry {
|
|
12
|
+
readonly fixture: string;
|
|
13
|
+
readonly modulePattern: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const CAPABILITIES: readonly CapabilityEntry[] = [
|
|
17
|
+
{ fixture: 'cursor', modulePattern: 'webCursor' },
|
|
18
|
+
{ fixture: 'glyph', modulePattern: 'webGlyphRasterizer' },
|
|
19
|
+
{ fixture: 'loop', modulePattern: 'webLoop' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
interface FixtureResult {
|
|
23
|
+
modules: string[];
|
|
24
|
+
rawBytes: number;
|
|
25
|
+
gzipBytes: number;
|
|
26
|
+
code: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function resolveWorkspaceAliases(): Record<string, string> {
|
|
30
|
+
const packagesDir = resolve(ROOT, 'packages');
|
|
31
|
+
const alias: Record<string, string> = {};
|
|
32
|
+
const entries = readdirSync(packagesDir, { withFileTypes: true });
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (!entry.isDirectory()) continue;
|
|
35
|
+
const pkgJsonPath = resolve(packagesDir, entry.name, 'package.json');
|
|
36
|
+
if (!existsSync(pkgJsonPath)) continue;
|
|
37
|
+
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
38
|
+
if (typeof pkgJson.name === 'string') {
|
|
39
|
+
alias[pkgJson.name] = resolve(packagesDir, entry.name, 'src');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return alias;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function buildFixture(name: string): Promise<FixtureResult> {
|
|
46
|
+
const entry = resolve(EVIDENCE_DIR, `${name}.ts`);
|
|
47
|
+
const alias = resolveWorkspaceAliases();
|
|
48
|
+
|
|
49
|
+
const result = (await build({
|
|
50
|
+
configFile: false,
|
|
51
|
+
root: EVIDENCE_DIR,
|
|
52
|
+
logLevel: 'silent',
|
|
53
|
+
resolve: { alias },
|
|
54
|
+
build: {
|
|
55
|
+
write: false,
|
|
56
|
+
minify: false,
|
|
57
|
+
target: 'esnext',
|
|
58
|
+
sourcemap: false,
|
|
59
|
+
rollupOptions: {
|
|
60
|
+
input: entry,
|
|
61
|
+
output: { format: 'es' },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
})) as RollupOutput;
|
|
65
|
+
|
|
66
|
+
const chunks = result.output.filter((o): o is OutputChunk => o.type === 'chunk');
|
|
67
|
+
const mainChunk = chunks.find((c) => c.isEntry) ?? chunks[0];
|
|
68
|
+
const allModules = new Set<string>();
|
|
69
|
+
for (const chunk of chunks) {
|
|
70
|
+
for (const id of Object.keys(chunk.modules)) {
|
|
71
|
+
allModules.add(id);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const code = mainChunk.code;
|
|
76
|
+
const rawBytes = Buffer.byteLength(code, 'utf-8');
|
|
77
|
+
const gzipBytes = gzipSync(code).byteLength;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
code,
|
|
81
|
+
gzipBytes,
|
|
82
|
+
modules: [...allModules].map((id) => id.replace(ROOT + '/', '')),
|
|
83
|
+
rawBytes,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sourceModules(modules: readonly string[]): string[] {
|
|
88
|
+
return modules.filter((m) => !m.includes('/evidence/'));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function hasHostWebModule(modules: readonly string[]): boolean {
|
|
92
|
+
return sourceModules(modules).some((m) => m.includes('packages/host-web/'));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function hasCapabilityModule(modules: readonly string[], pattern: string): boolean {
|
|
96
|
+
return sourceModules(modules).some((m) => m.includes(pattern));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
describe('evidence: tree-shaking isolation', () => {
|
|
100
|
+
const results = new Map<string, FixtureResult>();
|
|
101
|
+
|
|
102
|
+
async function getFixture(name: string): Promise<FixtureResult> {
|
|
103
|
+
let result = results.get(name);
|
|
104
|
+
if (result === undefined) {
|
|
105
|
+
result = await buildFixture(name);
|
|
106
|
+
results.set(name, result);
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
it('control fixture contains zero host-web modules', async () => {
|
|
112
|
+
const { modules } = await getFixture('control');
|
|
113
|
+
expect(hasHostWebModule(modules)).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('capability fixture contains zero host-web modules', async () => {
|
|
117
|
+
const { modules } = await getFixture('capability');
|
|
118
|
+
expect(sourceModules(modules).length).toBeGreaterThan(0);
|
|
119
|
+
expect(hasHostWebModule(modules)).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
for (const cap of CAPABILITIES) {
|
|
123
|
+
for (const other of CAPABILITIES) {
|
|
124
|
+
if (other === cap) continue;
|
|
125
|
+
it(`${cap.fixture} fixture excludes ${other.fixture} modules`, async () => {
|
|
126
|
+
const { modules } = await getFixture(cap.fixture);
|
|
127
|
+
expect(sourceModules(modules).length).toBeGreaterThan(0);
|
|
128
|
+
expect(hasHostWebModule(modules)).toBe(true);
|
|
129
|
+
expect(hasCapabilityModule(modules, other.modulePattern)).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
it('combined module set is within the union of individual capabilities', async () => {
|
|
135
|
+
const individualResults = await Promise.all(CAPABILITIES.map((cap) => getFixture(cap.fixture)));
|
|
136
|
+
const combinedResult = await getFixture('combined');
|
|
137
|
+
const union = new Set(individualResults.flatMap((r) => sourceModules(r.modules)));
|
|
138
|
+
const outsideUnion = sourceModules(combinedResult.modules).filter((m) => !union.has(m));
|
|
139
|
+
expect(outsideUnion).toEqual([]);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('normalized subadditivity: S(combined) + (N-1)*S(control) <= sum(S(individual))', async () => {
|
|
143
|
+
const control = await getFixture('control');
|
|
144
|
+
const combined = await getFixture('combined');
|
|
145
|
+
const individualResults = await Promise.all(CAPABILITIES.map((cap) => getFixture(cap.fixture)));
|
|
146
|
+
const n = CAPABILITIES.length;
|
|
147
|
+
|
|
148
|
+
for (const [name, fixture] of CAPABILITIES.map((cap, i) => [cap.fixture, individualResults[i]] as const)) {
|
|
149
|
+
const rawDelta = fixture.rawBytes - control.rawBytes;
|
|
150
|
+
const gzipDelta = fixture.gzipBytes - control.gzipBytes;
|
|
151
|
+
console.log(
|
|
152
|
+
`${name}: raw=${fixture.rawBytes} (${rawDelta >= 0 ? '+' : ''}${rawDelta}), ` +
|
|
153
|
+
`gzip=${fixture.gzipBytes} (${gzipDelta >= 0 ? '+' : ''}${gzipDelta})`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
console.log(`combined: raw=${combined.rawBytes}, gzip=${combined.gzipBytes}`);
|
|
157
|
+
console.log(`control: raw=${control.rawBytes}, gzip=${control.gzipBytes}`);
|
|
158
|
+
|
|
159
|
+
const sumRaw = individualResults.reduce((s, r) => s + r.rawBytes, 0);
|
|
160
|
+
const sumGzip = individualResults.reduce((s, r) => s + r.gzipBytes, 0);
|
|
161
|
+
|
|
162
|
+
for (const cap of CAPABILITIES) {
|
|
163
|
+
const individual = individualResults[CAPABILITIES.indexOf(cap)];
|
|
164
|
+
expect(individual.rawBytes).toBeGreaterThan(control.rawBytes);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
expect(combined.rawBytes).toBeGreaterThan(Math.max(...individualResults.map((r) => r.rawBytes)));
|
|
168
|
+
|
|
169
|
+
expect(combined.rawBytes + (n - 1) * control.rawBytes).toBeLessThanOrEqual(sumRaw);
|
|
170
|
+
expect(combined.gzipBytes + (n - 1) * control.gzipBytes).toBeLessThanOrEqual(sumGzip);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { enableHostWebAccessibility, resetHostWebAccessibilityForTest } from './webAccessibility';
|
|
2
|
+
|
|
3
|
+
describe('enableHostWebAccessibility', () => {
|
|
4
|
+
afterEach(() => resetHostWebAccessibilityForTest());
|
|
5
|
+
|
|
6
|
+
it('does not throw on first call', () => {
|
|
7
|
+
expect(() => enableHostWebAccessibility()).not.toThrow();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('is idempotent', () => {
|
|
11
|
+
enableHostWebAccessibility();
|
|
12
|
+
expect(() => enableHostWebAccessibility()).not.toThrow();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('resetHostWebAccessibilityForTest', () => {
|
|
17
|
+
it('allows re-enabling after reset', () => {
|
|
18
|
+
enableHostWebAccessibility();
|
|
19
|
+
resetHostWebAccessibilityForTest();
|
|
20
|
+
expect(() => enableHostWebAccessibility()).not.toThrow();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { enableHostWebApp, resetHostWebAppForTest } from './webApp';
|
|
2
|
+
|
|
3
|
+
describe('enableHostWebApp', () => {
|
|
4
|
+
afterEach(() => resetHostWebAppForTest());
|
|
5
|
+
|
|
6
|
+
it('does not throw on first call', () => {
|
|
7
|
+
expect(() => enableHostWebApp()).not.toThrow();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('is idempotent', () => {
|
|
11
|
+
enableHostWebApp();
|
|
12
|
+
expect(() => enableHostWebApp()).not.toThrow();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('resetHostWebAppForTest', () => {
|
|
17
|
+
it('allows re-enabling after reset', () => {
|
|
18
|
+
enableHostWebApp();
|
|
19
|
+
resetHostWebAppForTest();
|
|
20
|
+
expect(() => enableHostWebApp()).not.toThrow();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { enableHostWebClipboard, resetHostWebClipboardForTest } from './webClipboard';
|
|
2
|
+
|
|
3
|
+
describe('enableHostWebClipboard', () => {
|
|
4
|
+
afterEach(() => resetHostWebClipboardForTest());
|
|
5
|
+
|
|
6
|
+
it('does not throw on first call', () => {
|
|
7
|
+
expect(() => enableHostWebClipboard()).not.toThrow();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('is idempotent', () => {
|
|
11
|
+
enableHostWebClipboard();
|
|
12
|
+
expect(() => enableHostWebClipboard()).not.toThrow();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('resetHostWebClipboardForTest', () => {
|
|
17
|
+
it('allows re-enabling after reset', () => {
|
|
18
|
+
enableHostWebClipboard();
|
|
19
|
+
resetHostWebClipboardForTest();
|
|
20
|
+
expect(() => enableHostWebClipboard()).not.toThrow();
|
|
21
|
+
});
|
|
22
|
+
});
|