@signageos/front-applet 6.5.5 → 6.5.7

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.
@@ -44,37 +44,35 @@ sos.browser.open('https://www.signageos.io'); // Open link in the browser
44
44
  ```
45
45
  <br/>
46
46
 
47
- Method `open()` also supports properties for browser. You can set height, width or CORS domains. All properties are optional.
48
-
49
-
50
- | Property | Type | Description |
51
- | -------- | ------ | -------- |
52
- | `aclDomains` | Array | ? |
53
- | `aclMode` | String | Can be only **blacklist** or **whitelist**. |
54
- | `readOnlyAddressBar` | Boolean | Accessible address bar |
55
- | `coordinates` | Object | Size of browser screen (only Linux) |
56
- | `idleTimeout` | Number | Timeout in milliseconds for loading page |
57
- | `theme` | Object | Setting custom theme for Android |
58
- | `headlessMode` | Boolean | Headless mode hides the entire address bar (default) |
59
- | `canUserClose` | Boolean | Whether the user can manually close the browser. Default:<br/>**Headless:** `false`<br/>**With UI:** `true` |
60
- | `clearData` | Boolean | Clear cache after the browser closes. Default:<br/>**Headless:** `false`<br/>**With UI:** `true`
61
- | `method` | String | Can only be **native** (which opens a new, fully sandboxed fullscreen window) or **iframe** (which opens a configurable-sized window). (only Linux) |
62
- :::
63
-
47
+ Method `open()` also supports properties for browser, all of which are optional.
48
+
49
+ | Property | Type | Description |
50
+ |----------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
51
+ | `aclDomains` | Array | List of domains to be interpreted according to `aclMode`. Example: `signageos.io`, `www.example.com` |
52
+ | `aclMode` | String | <ul><li>`blacklist` Allow access to all domains _except_ those in `aclDomains` and their subdomains.</li><li>`whitelist` – Allow access _only_ to domains in `aclDomains` and their subdomains.</li></ul>
53
+ | `readOnlyAddressBar` | Boolean | <ul><li>`true` The address bar is read-only.</li><li>`false` The user can navigate away by entering a URL in the address bar.</li></ul> |
54
+ | `coordinates` | Object | Size and position of the browser window. Defaults to fullscreen. (Android, Linux)
55
+ | `idleTimeout` | Number | The browser will automatically close after a specified period of inactivity (in milliseconds). |
56
+ | `theme` | Object | Specify custom UI theme. (Android) |
57
+ | `headlessMode` | Boolean | Headless mode hides the entire address bar (default) |
58
+ | `canUserClose` | Boolean | Whether the user can manually close the browser. Default:<br/>**Headless:** `false`<br/>**With UI:** `true` |
59
+ | `clearData` | Boolean | Clear cache after the browser closes. Default:<br/>**Headless:** `false`<br/>**With UI:** `true` |
60
+ | `method` | String | Can only be **native** (which opens a new, fully sandboxed fullscreen window) or **iframe** (which opens a configurable-sized window). (only Linux) |
64
61
 
65
62
  ```javascript
66
63
  sos.browser.open('https://www.signageos.io', {
67
- aclDomains: ['google.com', 'yahoo.com'],
68
- aclMode: 'blacklist', // or 'whitelist'
69
- readOnlyAddressBar: true,
70
- coordinates: { // Supported only on Linux and Android
71
- x: 0,
72
- y: 0,
73
- height: 500,
74
- width: 500,
75
- },
76
- // theme: { ... } // supported only on Android
77
- headlessMode: false, // supported only on Android
64
+ aclDomains: ['google.com', 'yahoo.com'],
65
+ aclMode: 'blacklist', // or 'whitelist'
66
+ readOnlyAddressBar: true,
67
+ coordinates: { // Supported only on Linux and Android
68
+ x: 0,
69
+ y: 0,
70
+ height: 500,
71
+ width: 500,
72
+ },
73
+ // theme: { ... } // supported only on Android
74
+ headlessMode: false, // supported only on Android
75
+ });
78
76
  ```
79
77
 
80
78
  :::note[GitHub Example]
@@ -4,15 +4,21 @@ import IKeyUpEvent from './IKeyUpEvent';
4
4
  import { IInput } from './IInput';
5
5
  export default class Input implements IInput {
6
6
  readonly window: Window;
7
- private messagePrefix;
8
- static MESSAGE_PREFIX: string;
9
- private eventEmitter;
7
+ private readonly messagePrefix;
8
+ static readonly MESSAGE_PREFIX: string;
9
+ private readonly eventEmitter;
10
+ private readonly hasWindowEventListener;
11
+ private alive;
10
12
  constructor(window: Window, messagePrefix: string);
13
+ destroy(): void;
11
14
  onKeyUp(listener: IKeyUpEventListener): void;
12
15
  handleMessageData(data: IInputKeyMessage): void;
13
16
  removeEventListeners(): void;
14
17
  removeEventListener(event: string, listener: (...args: any[]) => void): void;
15
18
  emitKeyUpEvent(event: IKeyUpEvent): void;
19
+ private isTopLevelFrame;
20
+ private canAccessParentOrigin;
16
21
  private dispatchEventToParent;
17
22
  private getMessage;
23
+ private checkAlive;
18
24
  }
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const events_1 = require("events");
13
4
  const Validate_1 = require("../Validate/Validate");
@@ -16,9 +7,39 @@ class Input {
16
7
  this.window = window;
17
8
  this.messagePrefix = messagePrefix;
18
9
  this.eventEmitter = new events_1.EventEmitter();
19
- this.window.addEventListener('keyup', (event) => this.dispatchEventToParent(event));
10
+ this.hasWindowEventListener = false;
11
+ this.alive = true;
12
+ this.dispatchEventToParent = (event) => {
13
+ try {
14
+ this.window.parent.document.dispatchEvent(new KeyboardEvent('keyup', event));
15
+ }
16
+ catch (e) {
17
+ if (e instanceof ReferenceError) {
18
+ // KeyboardEvent constructor isn't available during tests.
19
+ // TODO Mock KeyboardEvent constructor during tests.
20
+ this.window.parent.document.dispatchEvent(event);
21
+ }
22
+ else {
23
+ throw e;
24
+ }
25
+ }
26
+ };
27
+ if (!this.isTopLevelFrame() && this.canAccessParentOrigin()) {
28
+ this.hasWindowEventListener = true;
29
+ this.window.addEventListener('keyup', this.dispatchEventToParent);
30
+ }
31
+ }
32
+ destroy() {
33
+ if (this.alive) {
34
+ this.alive = false;
35
+ this.removeEventListeners();
36
+ if (this.hasWindowEventListener) {
37
+ this.window.removeEventListener('keyup', this.dispatchEventToParent);
38
+ }
39
+ }
20
40
  }
21
41
  onKeyUp(listener) {
42
+ this.checkAlive();
22
43
  Validate_1.default({ listener }).required().function();
23
44
  this.eventEmitter.addListener('keyup', listener);
24
45
  }
@@ -30,7 +51,7 @@ class Input {
30
51
  keyCode: data.keyCode,
31
52
  keyName: data.keyName,
32
53
  };
33
- this.eventEmitter.emit('keyup', keyupEvent);
54
+ this.emitKeyUpEvent(keyupEvent);
34
55
  break;
35
56
  default:
36
57
  }
@@ -42,22 +63,42 @@ class Input {
42
63
  this.eventEmitter.removeListener(event, listener);
43
64
  }
44
65
  emitKeyUpEvent(event) {
66
+ this.checkAlive();
45
67
  this.eventEmitter.emit('keyup', event);
46
68
  }
47
- dispatchEventToParent(event) {
48
- var _a, _b, _c;
49
- return __awaiter(this, void 0, void 0, function* () {
50
- if ((_c = (_b = (_a = this.window) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.document) === null || _c === void 0 ? void 0 : _c.dispatchEvent) {
51
- this.window.parent.document.dispatchEvent(new KeyboardEvent('keyup', event));
69
+ isTopLevelFrame() {
70
+ return this.window === this.window.parent;
71
+ }
72
+ canAccessParentOrigin() {
73
+ var _a, _b;
74
+ try {
75
+ const hasParent = !!((_b = (_a = this.window) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.document);
76
+ if (!hasParent) {
77
+ console.warn('Parent window or document is not defined');
78
+ }
79
+ return hasParent;
80
+ }
81
+ catch (e) {
82
+ if (e instanceof DOMException) {
83
+ // Blocked a frame with origin "..." from accessing a cross-origin frame.
84
+ // This will happen on Android when applets have https://appassets.android.signageos.io origin
85
+ // and top-level frame has file:// origin. Android doesn't benefit from this hack anyway.
86
+ console.warn('Parent document is not accessible');
87
+ return false;
52
88
  }
53
89
  else {
54
- console.warn('Parent window or document is not defined');
90
+ throw e;
55
91
  }
56
- });
92
+ }
57
93
  }
58
94
  getMessage(name) {
59
95
  return this.messagePrefix + '.' + Input.MESSAGE_PREFIX + '.' + name;
60
96
  }
97
+ checkAlive() {
98
+ if (!this.alive) {
99
+ throw new Error('destroyed');
100
+ }
101
+ }
61
102
  }
62
103
  exports.default = Input;
63
104
  Input.MESSAGE_PREFIX = 'input';
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../src/FrontApplet/Input/Input.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,mCAAsC;AAItC,mDAA4C;AAG5C,MAAqB,KAAK;IAIzB,YAA4B,MAAc,EAAU,aAAqB;QAA7C,WAAM,GAAN,MAAM,CAAQ;QAAU,kBAAa,GAAb,aAAa,CAAQ;QACxE,IAAI,CAAC,YAAY,GAAG,IAAI,qBAAY,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC;IACpG,CAAC;IAEM,OAAO,CAAC,QAA6B;QAC3C,kBAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAEM,iBAAiB,CAAC,IAAsB;QAC9C,QAAQ,IAAI,CAAC,IAAI,EAAE;YAClB,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC5B,MAAM,UAAU,GAAgB;oBAC/B,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;iBACrB,CAAC;gBACF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;gBAC5C,MAAM;YACP,QAAQ;SACR;IACF,CAAC;IAEM,oBAAoB;QAC1B,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC;IACxC,CAAC;IAEM,mBAAmB,CAAC,KAAa,EAAE,QAAkC;QAC3E,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IAEM,cAAc,CAAC,KAAkB;QACvC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IAEa,qBAAqB,CAAC,KAAoB;;;YACvD,IAAI,MAAA,MAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,MAAM,0CAAE,QAAQ,0CAAE,aAAa,EAAE;gBACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;aAC7E;iBAAM;gBACN,OAAO,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;aACzD;;KACD;IAEO,UAAU,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,aAAa,GAAG,GAAG,GAAG,KAAK,CAAC,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC;IACrE,CAAC;;AAlDF,wBAmDC;AAlDc,oBAAc,GAAW,OAAO,CAAC"}
1
+ {"version":3,"file":"Input.js","sourceRoot":"","sources":["../../../src/FrontApplet/Input/Input.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signageos/front-applet",
3
- "version": "6.5.5",
3
+ "version": "6.5.7",
4
4
  "main": "dist/bundle.js",
5
5
  "types": "es6/bundle.d.ts",
6
6
  "files": [
@@ -20,7 +20,7 @@
20
20
  "lint:prettier:fix": "prettier \"**/*.+(ts|tsx|json|js)\" --write",
21
21
  "lint:staged": "npx lint-staged",
22
22
  "prebuild": "rm -rf dist/*",
23
- "prepare": "npm run prebuild && npm run build && npm run generate-declarations && npx husky install",
23
+ "prepare": "npm run build && npm run generate-declarations && npx husky install",
24
24
  "test": "env NODE_ENV=test ./node_modules/mocha/bin/mocha --config .mocha/default.js",
25
25
  "test:coverage": "npm run test:coverage:runtime && npm run test:coverage:types",
26
26
  "test:coverage:runtime": "env NODE_ENV=test c8 ./node_modules/mocha/bin/mocha --config .mocha/transpile-only.js",