@raydiant/playlist-window-manager 0.14.20 → 0.14.23

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/README.md CHANGED
@@ -1,4 +1,10 @@
1
- Usage:
1
+ ## Deployment
2
+
3
+ ```
4
+ yarn deploy
5
+ ```
6
+
7
+ ## Usage
2
8
 
3
9
  ```js
4
10
 
@@ -52,9 +52,14 @@ var IFrameRenderer = /** @class */ (function () {
52
52
  console.warn("Invalid message received from iframe '" + JSON.stringify(event.data) + "', ignoring message");
53
53
  return;
54
54
  }
55
+ if (!windowId) {
56
+ // ignore messages that don't have windowId
57
+ // such message are comming from 3rd party IFrames like google
58
+ return;
59
+ }
55
60
  var window = _this.getWindow(windowId);
56
61
  if (!window) {
57
- throw new Error("Failed add receive message callback to window, missing window id '" + windowId + "'");
62
+ throw new Error("Failed add receive message callback to window, window with window id: '" + windowId + "' was not found");
58
63
  }
59
64
  if (window.receiveMessageCallback) {
60
65
  window.receiveMessageCallback(type, payload);
@@ -351,7 +351,7 @@ var PresentationWindow = /** @class */ (function () {
351
351
  _a = this.options, applicationVersion = _a.applicationVersion, windowId = _a.windowId;
352
352
  if (!this.isEmbeddedApp()) return [3 /*break*/, 3];
353
353
  if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 2];
354
- url = embeddedApps_1.default(this.presentation, applicationVersion.embeddedUrlFormat);
354
+ url = embeddedApps_1.default(this.presentation, applicationVersion);
355
355
  this.logInfo("Reload window '" + windowId + "' for embedded app url '" + url + "'");
356
356
  return [4 /*yield*/, this.loadWindow(url)];
357
357
  case 1:
@@ -412,7 +412,7 @@ var PresentationWindow = /** @class */ (function () {
412
412
  if (!applicationVersion.embeddedUrlFormat) {
413
413
  throw new Error("Error loading embedded app, missing embeddedUrlFormat for '" + applicationVersion.id + "'");
414
414
  }
415
- url = embeddedApps_1.default(this.presentation, applicationVersion.embeddedUrlFormat);
415
+ url = embeddedApps_1.default(this.presentation, applicationVersion);
416
416
  this.logInfo("Create window '" + windowId + "' for embedded app url '" + url + "'");
417
417
  // Embedded apps should not have a backgroundColor bexcause some sites expect
418
418
  // the browser default of white will be applied. We also don't attach the message
@@ -1,2 +1,2 @@
1
- import { Presentation } from './types';
2
- export default function createEmbeddedApp(presentation: Presentation, embeddedUrlFormat: string): string;
1
+ import { Presentation, ApplicationVersion } from './types';
2
+ export default function createEmbeddedApp(presentation: Presentation, applicationVersion: ApplicationVersion): string;
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- function createEmbeddedApp(presentation, embeddedUrlFormat) {
3
+ function createEmbeddedApp(presentation, applicationVersion) {
4
4
  // build matches
5
5
  var parameterRegex = /(:([\w]+))(.?$|[^\w])/gm;
6
6
  var matches = [];
7
7
  var match = null;
8
8
  do {
9
- match = parameterRegex.exec(embeddedUrlFormat);
9
+ match = parameterRegex.exec(applicationVersion.embeddedUrlFormat || '');
10
10
  if (match) {
11
11
  matches.push(match);
12
12
  }
13
13
  } while (match !== null);
14
14
  // replace
15
- var url = embeddedUrlFormat;
15
+ var url = applicationVersion.embeddedUrlFormat || '';
16
16
  matches.forEach(function (m) {
17
17
  var variable = m[1];
18
18
  var _a = variable.split(':'), variableName = _a[1];
@@ -20,9 +20,15 @@ function createEmbeddedApp(presentation, embeddedUrlFormat) {
20
20
  // port numbers in the embedded app url.
21
21
  if (!isNaN(Number(variableName)))
22
22
  return;
23
+ var presentationProperty = applicationVersion.presentationProperties.find(function (p) { return p.name === variableName; });
24
+ // If the presentation property is not found (this shouldn't happen), default to encoding the value.
25
+ // Otherwise, only skip encoding if the presentation property's encode property is false.
26
+ var shouldEncodeValue = !presentationProperty || presentationProperty.encode !== false;
23
27
  var value = presentation.applicationVariables[m[2]];
24
28
  if (value === undefined)
25
29
  value = '';
30
+ if (shouldEncodeValue)
31
+ value = encodeURIComponent(value);
26
32
  url = url.replace(variable, value);
27
33
  });
28
34
  return url;
@@ -22,18 +22,44 @@ var createPresentation = function (overrides) { return (__assign({ id: 'id', nam
22
22
  },
23
23
  presentationsPlaylists: []
24
24
  } }, overrides)); };
25
+ var createApplicationVersion = function (overrides) { return (__assign({ id: 'id', name: 'name', applicationId: 'applicationId', embeddedUrlFormat: null, configurableDuration: false, sourceUrl: null, presentationProperties: [] }, overrides)); };
25
26
  test('Replaces variable in query parameteers', function () {
26
- expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), 'https://example.com?foo=:foo')).toBe('https://example.com?foo=bar');
27
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), createApplicationVersion({
28
+ embeddedUrlFormat: 'https://example.com?foo=:foo'
29
+ }))).toBe('https://example.com?foo=bar');
27
30
  });
28
31
  test('Replaces variable in path', function () {
29
- expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), 'https://example.com/:foo')).toBe('https://example.com/bar');
32
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), createApplicationVersion({
33
+ embeddedUrlFormat: 'https://example.com/:foo'
34
+ }))).toBe('https://example.com/bar');
30
35
  });
31
36
  test('Replaces undefined variable with empty string', function () {
32
- expect(embeddedApps_1.default(createPresentation({ applicationVariables: {} }), 'https://example.com/:foo')).toBe('https://example.com/');
37
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: {} }), createApplicationVersion({
38
+ embeddedUrlFormat: 'https://example.com/:foo'
39
+ }))).toBe('https://example.com/');
33
40
  });
34
41
  test('Replaces variable with underscore', function () {
35
- expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo_1: 'bar' } }), 'https://example.com/:foo_1')).toBe('https://example.com/bar');
42
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo_1: 'bar' } }), createApplicationVersion({
43
+ embeddedUrlFormat: 'https://example.com/:foo_1'
44
+ }))).toBe('https://example.com/bar');
36
45
  });
37
46
  test('Does not replace variable that is a number', function () {
38
- expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), 'http://localhost:8080?foo=:foo')).toBe('http://localhost:8080?foo=bar');
47
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: 'bar' } }), createApplicationVersion({
48
+ embeddedUrlFormat: 'http://localhost:8080?foo=:foo'
49
+ }))).toBe('http://localhost:8080?foo=bar');
50
+ });
51
+ test('Encodes a variables containing special characters', function () {
52
+ var fooValue = 'Lorem Ipsum. !@#$%^&*()-. More Text';
53
+ var fooValueEncoded = 'Lorem%20Ipsum.%20!%40%23%24%25%5E%26*()-.%20More%20Text';
54
+ expect(embeddedApps_1.default(createPresentation({ applicationVariables: { foo: fooValue } }), createApplicationVersion({
55
+ embeddedUrlFormat: "http://localhost:8080?foo=:foo"
56
+ }))).toBe("http://localhost:8080?foo=" + fooValueEncoded);
57
+ });
58
+ test('Does not encode value if presentation property disables encoding', function () {
59
+ expect(embeddedApps_1.default(createPresentation({
60
+ applicationVariables: { url: 'https://raydiant.com' }
61
+ }), createApplicationVersion({
62
+ embeddedUrlFormat: ":url",
63
+ presentationProperties: [{ name: 'url', encode: false }]
64
+ }))).toBe("https://raydiant.com");
39
65
  });
package/build/types.d.ts CHANGED
@@ -27,6 +27,10 @@ export interface ApplicationVersion {
27
27
  embeddedUrlFormat: string | null;
28
28
  configurableDuration: boolean;
29
29
  sourceUrl: string | null;
30
+ presentationProperties: Array<{
31
+ name: string;
32
+ encode?: boolean;
33
+ }>;
30
34
  }
31
35
  export interface Font {
32
36
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raydiant/playlist-window-manager",
3
- "version": "0.14.20",
3
+ "version": "0.14.23",
4
4
  "description": "Window manager for playlist playback.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -202,10 +202,16 @@ export default class IFrameRenderer implements PresentationWindowRenderer {
202
202
  return;
203
203
  }
204
204
 
205
+ if (!windowId) {
206
+ // ignore messages that don't have windowId
207
+ // such message are comming from 3rd party IFrames like google
208
+ return;
209
+ }
210
+
205
211
  const window = this.getWindow(windowId);
206
212
  if (!window) {
207
213
  throw new Error(
208
- `Failed add receive message callback to window, missing window id '${windowId}'`
214
+ `Failed add receive message callback to window, window with window id: '${windowId}' was not found`
209
215
  );
210
216
  }
211
217
 
@@ -299,10 +299,7 @@ export default class PresentationWindow {
299
299
 
300
300
  if (this.isEmbeddedApp()) {
301
301
  if (applicationVersion.embeddedUrlFormat) {
302
- const url = createEmbeddedApp(
303
- this.presentation,
304
- applicationVersion.embeddedUrlFormat
305
- );
302
+ const url = createEmbeddedApp(this.presentation, applicationVersion);
306
303
 
307
304
  this.logInfo(
308
305
  `Reload window '${windowId}' for embedded app url '${url}'`
@@ -368,10 +365,7 @@ export default class PresentationWindow {
368
365
  );
369
366
  }
370
367
 
371
- const url = createEmbeddedApp(
372
- this.presentation,
373
- applicationVersion.embeddedUrlFormat
374
- );
368
+ const url = createEmbeddedApp(this.presentation, applicationVersion);
375
369
 
376
370
  this.logInfo(`Create window '${windowId}' for embedded app url '${url}'`);
377
371
 
@@ -1,5 +1,5 @@
1
1
  import createEmbeddedApp from './embeddedApps';
2
- import { Presentation } from './types';
2
+ import { Presentation, ApplicationVersion } from './types';
3
3
 
4
4
  const createPresentation = (
5
5
  overrides: Partial<Presentation>
@@ -20,11 +20,26 @@ const createPresentation = (
20
20
  ...overrides
21
21
  });
22
22
 
23
+ const createApplicationVersion = (
24
+ overrides: Partial<ApplicationVersion>
25
+ ): ApplicationVersion => ({
26
+ id: 'id',
27
+ name: 'name',
28
+ applicationId: 'applicationId',
29
+ embeddedUrlFormat: null,
30
+ configurableDuration: false,
31
+ sourceUrl: null,
32
+ presentationProperties: [],
33
+ ...overrides
34
+ });
35
+
23
36
  test('Replaces variable in query parameteers', () => {
24
37
  expect(
25
38
  createEmbeddedApp(
26
39
  createPresentation({ applicationVariables: { foo: 'bar' } }),
27
- 'https://example.com?foo=:foo'
40
+ createApplicationVersion({
41
+ embeddedUrlFormat: 'https://example.com?foo=:foo'
42
+ })
28
43
  )
29
44
  ).toBe('https://example.com?foo=bar');
30
45
  });
@@ -33,7 +48,9 @@ test('Replaces variable in path', () => {
33
48
  expect(
34
49
  createEmbeddedApp(
35
50
  createPresentation({ applicationVariables: { foo: 'bar' } }),
36
- 'https://example.com/:foo'
51
+ createApplicationVersion({
52
+ embeddedUrlFormat: 'https://example.com/:foo'
53
+ })
37
54
  )
38
55
  ).toBe('https://example.com/bar');
39
56
  });
@@ -42,7 +59,9 @@ test('Replaces undefined variable with empty string', () => {
42
59
  expect(
43
60
  createEmbeddedApp(
44
61
  createPresentation({ applicationVariables: {} }),
45
- 'https://example.com/:foo'
62
+ createApplicationVersion({
63
+ embeddedUrlFormat: 'https://example.com/:foo'
64
+ })
46
65
  )
47
66
  ).toBe('https://example.com/');
48
67
  });
@@ -51,7 +70,9 @@ test('Replaces variable with underscore', () => {
51
70
  expect(
52
71
  createEmbeddedApp(
53
72
  createPresentation({ applicationVariables: { foo_1: 'bar' } }),
54
- 'https://example.com/:foo_1'
73
+ createApplicationVersion({
74
+ embeddedUrlFormat: 'https://example.com/:foo_1'
75
+ })
55
76
  )
56
77
  ).toBe('https://example.com/bar');
57
78
  });
@@ -60,7 +81,38 @@ test('Does not replace variable that is a number', () => {
60
81
  expect(
61
82
  createEmbeddedApp(
62
83
  createPresentation({ applicationVariables: { foo: 'bar' } }),
63
- 'http://localhost:8080?foo=:foo'
84
+ createApplicationVersion({
85
+ embeddedUrlFormat: 'http://localhost:8080?foo=:foo'
86
+ })
64
87
  )
65
88
  ).toBe('http://localhost:8080?foo=bar');
66
89
  });
90
+
91
+ test('Encodes a variables containing special characters', () => {
92
+ const fooValue = 'Lorem Ipsum. !@#$%^&*()-. More Text';
93
+ const fooValueEncoded =
94
+ 'Lorem%20Ipsum.%20!%40%23%24%25%5E%26*()-.%20More%20Text';
95
+
96
+ expect(
97
+ createEmbeddedApp(
98
+ createPresentation({ applicationVariables: { foo: fooValue } }),
99
+ createApplicationVersion({
100
+ embeddedUrlFormat: `http://localhost:8080?foo=:foo`
101
+ })
102
+ )
103
+ ).toBe(`http://localhost:8080?foo=${fooValueEncoded}`);
104
+ });
105
+
106
+ test('Does not encode value if presentation property disables encoding', () => {
107
+ expect(
108
+ createEmbeddedApp(
109
+ createPresentation({
110
+ applicationVariables: { url: 'https://raydiant.com' }
111
+ }),
112
+ createApplicationVersion({
113
+ embeddedUrlFormat: `:url`,
114
+ presentationProperties: [{ name: 'url', encode: false }]
115
+ })
116
+ )
117
+ ).toBe(`https://raydiant.com`);
118
+ });
@@ -1,15 +1,15 @@
1
- import { Presentation } from './types';
1
+ import { Presentation, ApplicationVersion } from './types';
2
2
 
3
3
  export default function createEmbeddedApp(
4
4
  presentation: Presentation,
5
- embeddedUrlFormat: string
5
+ applicationVersion: ApplicationVersion
6
6
  ) {
7
7
  // build matches
8
8
  const parameterRegex = /(:([\w]+))(.?$|[^\w])/gm;
9
9
  const matches = [];
10
10
  let match = null;
11
11
  do {
12
- match = parameterRegex.exec(embeddedUrlFormat);
12
+ match = parameterRegex.exec(applicationVersion.embeddedUrlFormat || '');
13
13
 
14
14
  if (match) {
15
15
  matches.push(match);
@@ -17,7 +17,7 @@ export default function createEmbeddedApp(
17
17
  } while (match !== null);
18
18
 
19
19
  // replace
20
- let url = embeddedUrlFormat;
20
+ let url = applicationVersion.embeddedUrlFormat || '';
21
21
  matches.forEach(m => {
22
22
  const variable = m[1];
23
23
  const [, variableName] = variable.split(':');
@@ -25,8 +25,19 @@ export default function createEmbeddedApp(
25
25
  // port numbers in the embedded app url.
26
26
  if (!isNaN(Number(variableName))) return;
27
27
 
28
+ const presentationProperty = applicationVersion.presentationProperties.find(
29
+ p => p.name === variableName
30
+ );
31
+
32
+ // If the presentation property is not found (this shouldn't happen), default to encoding the value.
33
+ // Otherwise, only skip encoding if the presentation property's encode property is false.
34
+ const shouldEncodeValue =
35
+ !presentationProperty || presentationProperty.encode !== false;
36
+
28
37
  let value = presentation.applicationVariables[m[2]];
29
38
  if (value === undefined) value = '';
39
+ if (shouldEncodeValue) value = encodeURIComponent(value);
40
+
30
41
  url = url.replace(variable, value);
31
42
  });
32
43
 
package/src/types.ts CHANGED
@@ -25,6 +25,7 @@ export interface ApplicationVersion {
25
25
  embeddedUrlFormat: string | null;
26
26
  configurableDuration: boolean;
27
27
  sourceUrl: string | null;
28
+ presentationProperties: Array<{ name: string; encode?: boolean }>;
28
29
  }
29
30
 
30
31
  export interface Font {