@raydiant/playlist-window-manager 0.28.0 → 0.28.1

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.
@@ -4,6 +4,7 @@ export default class IFrameRenderer implements PresentationWindowRenderer {
4
4
  private windows;
5
5
  constructor(container: HTMLElement);
6
6
  createWindow({ windowId, bounds, backgroundColor, receiveMessageCallback, }: CreateWindowOptions): Promise<void>;
7
+ private loadWindowResolvers;
7
8
  loadWindow(windowId: string, url: string): Promise<void>;
8
9
  updateWindowBounds(windowId: string, bounds: WindowBounds): void;
9
10
  showWindow(windowId: string, isFocused: boolean): void;
@@ -42,6 +42,7 @@ var IFrameRenderer = /** @class */ (function () {
42
42
  var _this = this;
43
43
  this.container = container;
44
44
  this.windows = {};
45
+ this.loadWindowResolvers = [];
45
46
  this.globalMessageHandler = function (event) {
46
47
  // Ignore messages that don't start with the message prefix.
47
48
  if (typeof event.data === 'string' && event.data.startsWith(namespace)) {
@@ -106,18 +107,35 @@ var IFrameRenderer = /** @class */ (function () {
106
107
  });
107
108
  };
108
109
  IFrameRenderer.prototype.loadWindow = function (windowId, url) {
110
+ var _this = this;
109
111
  var window = this.getWindow(windowId);
110
112
  if (!window) {
111
113
  throw new Error("Failed to update window bounds, missing window id '".concat(windowId, "'"));
112
114
  }
113
115
  // Return a promise that resolves then the window has successfully loaded.
114
116
  return new Promise(function (resolve, reject) {
115
- window.frame.onload = function () {
116
- resolve();
117
- };
118
- window.frame.onerror = function () {
119
- reject(new Error("Error loading window for '".concat(url, "'")));
120
- };
117
+ _this.loadWindowResolvers.push([resolve, reject]);
118
+ // If we reassign onload, we may lost any pending promise called previously.
119
+ // Basically, if this function is called a first time, then it's called a
120
+ // second time without the first one completes load, the resolve callback
121
+ // will never be called, and the code that is awaiting for the promise will
122
+ // never be fulfilled.
123
+ if (!window.frame.onload) {
124
+ window.frame.onload = function () {
125
+ while (_this.loadWindowResolvers.length) {
126
+ var resolve_1 = (_this.loadWindowResolvers.shift() || [])[0];
127
+ resolve_1 === null || resolve_1 === void 0 ? void 0 : resolve_1();
128
+ }
129
+ };
130
+ }
131
+ if (!window.frame.onerror) {
132
+ window.frame.onerror = function () {
133
+ while (_this.loadWindowResolvers.length) {
134
+ var _a = _this.loadWindowResolvers.shift() || [], _ = _a[0], reject_1 = _a[1];
135
+ reject_1 === null || reject_1 === void 0 ? void 0 : reject_1(new Error("Error loading window for '".concat(url, "'")));
136
+ }
137
+ };
138
+ }
121
139
  window.frame.src = url;
122
140
  });
123
141
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raydiant/playlist-window-manager",
3
- "version": "0.28.0",
3
+ "version": "0.28.1",
4
4
  "description": "Window manager for playlist playback.",
5
5
  "main": "build/index.js",
6
6
  "scripts": {
@@ -69,6 +69,8 @@ export default class IFrameRenderer implements PresentationWindowRenderer {
69
69
  this.container.appendChild(frame);
70
70
  }
71
71
 
72
+ private loadWindowResolvers: Array<[() => void, (err: Error) => void]> = [];
73
+
72
74
  public loadWindow(windowId: string, url: string) {
73
75
  const window = this.getWindow(windowId);
74
76
  if (!window) {
@@ -79,13 +81,30 @@ export default class IFrameRenderer implements PresentationWindowRenderer {
79
81
 
80
82
  // Return a promise that resolves then the window has successfully loaded.
81
83
  return new Promise<void>((resolve, reject) => {
82
- window.frame.onload = () => {
83
- resolve();
84
- };
84
+ this.loadWindowResolvers.push([resolve, reject]);
85
+
86
+ // If we reassign onload, we may lost any pending promise called previously.
87
+ // Basically, if this function is called a first time, then it's called a
88
+ // second time without the first one completes load, the resolve callback
89
+ // will never be called, and the code that is awaiting for the promise will
90
+ // never be fulfilled.
91
+ if (!window.frame.onload) {
92
+ window.frame.onload = () => {
93
+ while (this.loadWindowResolvers.length) {
94
+ const [resolve] = this.loadWindowResolvers.shift() || [];
95
+ resolve?.();
96
+ }
97
+ };
98
+ }
85
99
 
86
- window.frame.onerror = () => {
87
- reject(new Error(`Error loading window for '${url}'`));
88
- };
100
+ if (!window.frame.onerror) {
101
+ window.frame.onerror = () => {
102
+ while (this.loadWindowResolvers.length) {
103
+ const [_, reject] = this.loadWindowResolvers.shift() || [];
104
+ reject?.(new Error(`Error loading window for '${url}'`));
105
+ }
106
+ };
107
+ }
89
108
 
90
109
  window.frame.src = url;
91
110
  });