videomail-client 15.7.19 → 15.8.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.
@@ -10972,7 +10972,7 @@ var __webpack_exports__ = {};
10972
10972
  var client = __webpack_require__("Q");
10973
10973
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
10974
10974
  var package_namespaceObject = {
10975
- rE: "15.7.19"
10975
+ rE: "15.8.1"
10976
10976
  };
10977
10977
  function isAudioEnabled(options) {
10978
10978
  return Boolean(options.audio.enabled);
@@ -19290,7 +19290,8 @@ var __webpack_exports__ = {};
19290
19290
  }
19291
19291
  hasInvalidDimensions() {
19292
19292
  if (!this.rawVisualUserMedia) return false;
19293
- return this.rawVisualUserMedia.videoWidth < 3 || this.rawVisualUserMedia.videoHeight < 3;
19293
+ const { videoWidth, videoHeight } = this.rawVisualUserMedia;
19294
+ return videoWidth > 0 && videoWidth < 3 || videoHeight > 0 && videoHeight < 3;
19294
19295
  }
19295
19296
  logEvent(eventType, params) {
19296
19297
  this.options.logger.debug(`UserMedia: ... ${EVENT_ASCII} event ${eventType}: ${util_pretty(params)}`);
@@ -19629,13 +19630,16 @@ var __webpack_exports__ = {};
19629
19630
  }
19630
19631
  }
19631
19632
  sendPings() {
19633
+ this.stopPings();
19632
19634
  this.pingInterval = window.setInterval(()=>{
19633
19635
  this.options.logger.debug("Recorder: pinging...");
19634
19636
  this.writeStream(Buffer.from(""));
19635
19637
  }, this.options.timeouts.pingInterval);
19636
19638
  }
19637
19639
  stopPings() {
19638
- clearInterval(this.pingInterval);
19640
+ if (void 0 === this.pingInterval) return;
19641
+ window.clearInterval(this.pingInterval);
19642
+ this.pingInterval = void 0;
19639
19643
  }
19640
19644
  onAudioSample(audioSample) {
19641
19645
  this.samplesCount++;
@@ -19666,24 +19670,27 @@ var __webpack_exports__ = {};
19666
19670
  }
19667
19671
  }
19668
19672
  clearRetryTimeout() {
19669
- if (!this.retryTimeout) return;
19673
+ if (void 0 === this.retryTimeout) return;
19670
19674
  this.options.logger.debug("Recorder: clearRetryTimeout()");
19671
19675
  window.clearTimeout(this.retryTimeout);
19672
19676
  this.retryTimeout = void 0;
19673
19677
  }
19674
19678
  clearConnectionTimeout() {
19675
- if (!this.connectionTimeout) return;
19679
+ if (void 0 === this.connectionTimeout) return;
19676
19680
  this.options.logger.debug("Recorder: clearConnectionTimeout()");
19677
19681
  window.clearTimeout(this.connectionTimeout);
19678
19682
  this.connectionTimeout = void 0;
19679
19683
  }
19684
+ isOnline() {
19685
+ return navigator.onLine;
19686
+ }
19680
19687
  failConnection(params) {
19681
19688
  if (this.connectionFailed || this.connected || this.unloaded) return;
19682
19689
  this.connectionFailed = true;
19683
19690
  this.connecting = false;
19684
19691
  this.clearConnectionTimeout();
19685
19692
  const { url2Connect, cause } = params;
19686
- const online = navigator.onLine;
19693
+ const online = this.isOnline();
19687
19694
  const elapsedMs = this.connectingStartedAt ? Date.now() - this.connectingStartedAt : void 0;
19688
19695
  const closeEvent = this.lastCloseEvent;
19689
19696
  const socketError = this.lastSocketError;
@@ -19873,7 +19880,10 @@ var __webpack_exports__ = {};
19873
19880
  if (this.stream) {
19874
19881
  const connectionTimeoutMs = this.options.timeouts.connection;
19875
19882
  this.connectionTimeout = window.setTimeout(()=>{
19876
- this.failConnection({
19883
+ if (this.isOnline() && this.isUserMediaLoaded()) {
19884
+ this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
19885
+ this.initSocket();
19886
+ } else this.failConnection({
19877
19887
  url2Connect,
19878
19888
  cause: "timeout"
19879
19889
  });
@@ -20001,19 +20011,23 @@ var __webpack_exports__ = {};
20001
20011
  const characteristics = null == (_this_userMedia = this.userMedia) ? void 0 : _this_userMedia.getCharacteristics();
20002
20012
  this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? util_pretty(characteristics) : "none"}`);
20003
20013
  const errorListeners = this.getListeners("ERROR");
20004
- if (null == errorListeners ? void 0 : errorListeners.length) {
20005
- if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
20006
- const videomailError = error_createError({
20007
- err,
20008
- options: this.options,
20009
- usedConstraints
20010
- });
20011
- this.emit("ERROR", {
20012
- err: videomailError
20013
- });
20014
- } else this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
20015
- this.retryTimeout = window.setTimeout(this.initSocket.bind(this), this.options.timeouts.userMedia);
20016
- } else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
20014
+ if (null == errorListeners ? void 0 : errorListeners.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
20015
+ const videomailError = error_createError({
20016
+ err,
20017
+ options: this.options,
20018
+ usedConstraints
20019
+ });
20020
+ this.emit("ERROR", {
20021
+ err: videomailError
20022
+ });
20023
+ } else {
20024
+ this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
20025
+ this.retryTimeout = window.setTimeout(()=>{
20026
+ this.retryTimeout = void 0;
20027
+ this.loadUserMedia();
20028
+ }, this.options.timeouts.userMedia);
20029
+ }
20030
+ else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
20017
20031
  else {
20018
20032
  this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
20019
20033
  throw error_createError({
@@ -20070,8 +20084,8 @@ var __webpack_exports__ = {};
20070
20084
  ideal: idealHeight
20071
20085
  };
20072
20086
  }
20073
- this.options.logger.debug(`Recorder: our webcam constraints are: ${util_pretty(constraints)}`);
20074
- this.options.logger.debug(`Recorder: available webcam constraints are: ${util_pretty(navigator.mediaDevices.getSupportedConstraints())}`);
20087
+ this.options.logger.debug(util_summarize("Recorder: our webcam constraints are:", constraints));
20088
+ this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
20075
20089
  const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
20076
20090
  streamPromise.then((localStream)=>{
20077
20091
  this.getUserMediaCallback(localStream, params);
@@ -20237,7 +20251,8 @@ var __webpack_exports__ = {};
20237
20251
  limitReached
20238
20252
  });
20239
20253
  null == (_this_loop = this.loop) || _this_loop.complete();
20240
- setTimeout(()=>{
20254
+ this.stopTimeout = window.setTimeout(()=>{
20255
+ this.stopTimeout = void 0;
20241
20256
  this.stopTime = Date.now();
20242
20257
  const videoType = this.replay.getVideoType();
20243
20258
  if (!videoType) throw new Error("Unable to video record when no video type is defined.");
@@ -20287,6 +20302,9 @@ var __webpack_exports__ = {};
20287
20302
  this.reset();
20288
20303
  this.clearUserMediaTimeout();
20289
20304
  this.clearConnectionTimeout();
20305
+ this.clearRetryTimeout();
20306
+ this.clearStopTimeout();
20307
+ this.stopPings();
20290
20308
  this.connecting = false;
20291
20309
  if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
20292
20310
  if (this.submitting) ;
@@ -20310,12 +20328,17 @@ var __webpack_exports__ = {};
20310
20328
  }
20311
20329
  }
20312
20330
  clearUserMediaTimeout() {
20313
- if (this.userMediaTimeout) {
20331
+ if (void 0 !== this.userMediaTimeout) {
20314
20332
  this.options.logger.debug("Recorder: clearUserMediaTimeout()");
20315
20333
  window.clearTimeout(this.userMediaTimeout);
20316
20334
  this.userMediaTimeout = void 0;
20317
20335
  }
20318
20336
  }
20337
+ clearStopTimeout() {
20338
+ if (void 0 === this.stopTimeout) return;
20339
+ window.clearTimeout(this.stopTimeout);
20340
+ this.stopTimeout = void 0;
20341
+ }
20319
20342
  validate() {
20320
20343
  return this.connected && void 0 === this.canvas;
20321
20344
  }
@@ -20699,7 +20722,7 @@ var __webpack_exports__ = {};
20699
20722
  return this.userMediaLoaded;
20700
20723
  }
20701
20724
  constructor(visuals, replay, options){
20702
- super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
20725
+ super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "stopTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
20703
20726
  this.visuals = visuals;
20704
20727
  this.replay = replay;
20705
20728
  this.facingMode = options.video.facingMode;
@@ -21391,18 +21414,11 @@ var __webpack_exports__ = {};
21391
21414
  }
21392
21415
  initEvents(playerOnly = false) {
21393
21416
  this.options.logger.debug(`Container: initEvents (playerOnly = ${playerOnly})`);
21394
- if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", ()=>{
21395
- if (!this.built) return;
21396
- this.emit("WINDOW_RESIZE", "container");
21397
- });
21398
- if (this.options.enableAutoUnload) window.addEventListener("beforeunload", (e)=>{
21399
- this.unload({
21400
- e
21401
- });
21402
- }, {
21417
+ if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", this.handleWindowResize);
21418
+ if (this.options.enableAutoUnload) window.addEventListener("beforeunload", this.handleBeforeUnload, {
21403
21419
  once: true
21404
21420
  });
21405
- if (!playerOnly) this.visibility.onChange((visible)=>{
21421
+ if (!playerOnly) this.stopListeningToVisibility = this.visibility.onChange((visible)=>{
21406
21422
  if (this.built) if (visible) {
21407
21423
  if (isAutoPauseEnabled(this.options) && this.isCountingDown()) this.resume();
21408
21424
  this.emit("VISIBLE");
@@ -21412,19 +21428,7 @@ var __webpack_exports__ = {};
21412
21428
  }
21413
21429
  });
21414
21430
  if (this.options.enableSpace) {
21415
- if (!playerOnly) window.addEventListener("keydown", (e)=>{
21416
- const element = e.target;
21417
- const tagName = element.tagName;
21418
- const isEditable = element.isContentEditable || "true" === element.contentEditable;
21419
- if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase()) {
21420
- const code = e.code;
21421
- if ("Space" === code) {
21422
- e.preventDefault();
21423
- if (this.options.enablePause) this.visuals.pauseOrResume();
21424
- else this.visuals.recordOrStop();
21425
- }
21426
- }
21427
- });
21431
+ if (!playerOnly) window.addEventListener("keydown", this.handleKeyDown);
21428
21432
  }
21429
21433
  this.on("ERROR", (params)=>{
21430
21434
  this.processError(params);
@@ -21461,6 +21465,14 @@ var __webpack_exports__ = {};
21461
21465
  }
21462
21466
  this.endWaiting();
21463
21467
  }
21468
+ removeBrowserEventListeners() {
21469
+ var _this_stopListeningToVisibility, _this;
21470
+ window.removeEventListener("resize", this.handleWindowResize);
21471
+ window.removeEventListener("beforeunload", this.handleBeforeUnload);
21472
+ window.removeEventListener("keydown", this.handleKeyDown);
21473
+ null == (_this_stopListeningToVisibility = (_this = this).stopListeningToVisibility) || _this_stopListeningToVisibility.call(_this);
21474
+ this.stopListeningToVisibility = void 0;
21475
+ }
21464
21476
  hideMySelf() {
21465
21477
  html_hideElement(this.containerElement);
21466
21478
  }
@@ -21532,6 +21544,7 @@ var __webpack_exports__ = {};
21532
21544
  exc
21533
21545
  });
21534
21546
  } finally{
21547
+ this.removeBrowserEventListeners();
21535
21548
  this.removeAllListeners();
21536
21549
  this.built = this.submitted = false;
21537
21550
  }
@@ -21813,7 +21826,22 @@ var __webpack_exports__ = {};
21813
21826
  this.visuals.setLimitSeconds(limitSeconds);
21814
21827
  }
21815
21828
  constructor(options){
21816
- super("Container", options), container_define_property(this, "visibility", document_visibility_default()()), container_define_property(this, "htmlElement", document.querySelector("html")), container_define_property(this, "visuals", void 0), container_define_property(this, "buttons", void 0), container_define_property(this, "resource", void 0), container_define_property(this, "form", void 0), container_define_property(this, "hasError", false), container_define_property(this, "submitted", false), container_define_property(this, "lastValidation", false), container_define_property(this, "containerElement", void 0), container_define_property(this, "built", false);
21829
+ super("Container", options), container_define_property(this, "visibility", document_visibility_default()()), container_define_property(this, "htmlElement", document.querySelector("html")), container_define_property(this, "visuals", void 0), container_define_property(this, "buttons", void 0), container_define_property(this, "resource", void 0), container_define_property(this, "form", void 0), container_define_property(this, "hasError", false), container_define_property(this, "submitted", false), container_define_property(this, "lastValidation", false), container_define_property(this, "containerElement", void 0), container_define_property(this, "built", false), container_define_property(this, "stopListeningToVisibility", void 0), container_define_property(this, "handleWindowResize", ()=>{
21830
+ if (this.built) this.emit("WINDOW_RESIZE", "container");
21831
+ }), container_define_property(this, "handleBeforeUnload", (e)=>{
21832
+ this.unload({
21833
+ e
21834
+ });
21835
+ }), container_define_property(this, "handleKeyDown", (e)=>{
21836
+ const element = e.target;
21837
+ const tagName = element.tagName;
21838
+ const isEditable = element.isContentEditable || "true" === element.contentEditable;
21839
+ if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase() && "Space" === e.code) {
21840
+ e.preventDefault();
21841
+ if (this.options.enablePause) this.visuals.pauseOrResume();
21842
+ else this.visuals.recordOrStop();
21843
+ }
21844
+ });
21817
21845
  this.visuals = new wrappers_visuals(this, options);
21818
21846
  this.buttons = new buttons(this, options);
21819
21847
  this.resource = new src_resource(options);
package/dist/esm/index.js CHANGED
@@ -3620,7 +3620,7 @@ const constants = {
3620
3620
  }
3621
3621
  };
3622
3622
  var package_namespaceObject = {
3623
- rE: "15.7.19"
3623
+ rE: "15.8.1"
3624
3624
  };
3625
3625
  function isAudioEnabled(options) {
3626
3626
  return Boolean(options.audio.enabled);
@@ -6333,7 +6333,8 @@ class UserMedia extends util_Despot {
6333
6333
  }
6334
6334
  hasInvalidDimensions() {
6335
6335
  if (!this.rawVisualUserMedia) return false;
6336
- return this.rawVisualUserMedia.videoWidth < 3 || this.rawVisualUserMedia.videoHeight < 3;
6336
+ const { videoWidth, videoHeight } = this.rawVisualUserMedia;
6337
+ return videoWidth > 0 && videoWidth < 3 || videoHeight > 0 && videoHeight < 3;
6337
6338
  }
6338
6339
  logEvent(eventType, params) {
6339
6340
  this.options.logger.debug(`UserMedia: ... ${EVENT_ASCII} event ${eventType}: ${util_pretty(params)}`);
@@ -6658,13 +6659,16 @@ class Recorder extends util_Despot {
6658
6659
  }
6659
6660
  }
6660
6661
  sendPings() {
6662
+ this.stopPings();
6661
6663
  this.pingInterval = window.setInterval(()=>{
6662
6664
  this.options.logger.debug("Recorder: pinging...");
6663
6665
  this.writeStream(Buffer.from(""));
6664
6666
  }, this.options.timeouts.pingInterval);
6665
6667
  }
6666
6668
  stopPings() {
6667
- clearInterval(this.pingInterval);
6669
+ if (void 0 === this.pingInterval) return;
6670
+ window.clearInterval(this.pingInterval);
6671
+ this.pingInterval = void 0;
6668
6672
  }
6669
6673
  onAudioSample(audioSample) {
6670
6674
  this.samplesCount++;
@@ -6695,24 +6699,27 @@ class Recorder extends util_Despot {
6695
6699
  }
6696
6700
  }
6697
6701
  clearRetryTimeout() {
6698
- if (!this.retryTimeout) return;
6702
+ if (void 0 === this.retryTimeout) return;
6699
6703
  this.options.logger.debug("Recorder: clearRetryTimeout()");
6700
6704
  window.clearTimeout(this.retryTimeout);
6701
6705
  this.retryTimeout = void 0;
6702
6706
  }
6703
6707
  clearConnectionTimeout() {
6704
- if (!this.connectionTimeout) return;
6708
+ if (void 0 === this.connectionTimeout) return;
6705
6709
  this.options.logger.debug("Recorder: clearConnectionTimeout()");
6706
6710
  window.clearTimeout(this.connectionTimeout);
6707
6711
  this.connectionTimeout = void 0;
6708
6712
  }
6713
+ isOnline() {
6714
+ return navigator.onLine;
6715
+ }
6709
6716
  failConnection(params) {
6710
6717
  if (this.connectionFailed || this.connected || this.unloaded) return;
6711
6718
  this.connectionFailed = true;
6712
6719
  this.connecting = false;
6713
6720
  this.clearConnectionTimeout();
6714
6721
  const { url2Connect, cause } = params;
6715
- const online = navigator.onLine;
6722
+ const online = this.isOnline();
6716
6723
  const elapsedMs = this.connectingStartedAt ? Date.now() - this.connectingStartedAt : void 0;
6717
6724
  const closeEvent = this.lastCloseEvent;
6718
6725
  const socketError = this.lastSocketError;
@@ -6901,7 +6908,10 @@ class Recorder extends util_Despot {
6901
6908
  if (this.stream) {
6902
6909
  const connectionTimeoutMs = this.options.timeouts.connection;
6903
6910
  this.connectionTimeout = window.setTimeout(()=>{
6904
- this.failConnection({
6911
+ if (this.isOnline() && this.isUserMediaLoaded()) {
6912
+ this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
6913
+ this.initSocket();
6914
+ } else this.failConnection({
6905
6915
  url2Connect,
6906
6916
  cause: "timeout"
6907
6917
  });
@@ -7026,19 +7036,23 @@ class Recorder extends util_Despot {
7026
7036
  const characteristics = this.userMedia?.getCharacteristics();
7027
7037
  this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? util_pretty(characteristics) : "none"}`);
7028
7038
  const errorListeners = this.getListeners("ERROR");
7029
- if (errorListeners?.length) {
7030
- if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
7031
- const videomailError = error_createError({
7032
- err,
7033
- options: this.options,
7034
- usedConstraints
7035
- });
7036
- this.emit("ERROR", {
7037
- err: videomailError
7038
- });
7039
- } else this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
7040
- this.retryTimeout = window.setTimeout(this.initSocket.bind(this), this.options.timeouts.userMedia);
7041
- } else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
7039
+ if (errorListeners?.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
7040
+ const videomailError = error_createError({
7041
+ err,
7042
+ options: this.options,
7043
+ usedConstraints
7044
+ });
7045
+ this.emit("ERROR", {
7046
+ err: videomailError
7047
+ });
7048
+ } else {
7049
+ this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
7050
+ this.retryTimeout = window.setTimeout(()=>{
7051
+ this.retryTimeout = void 0;
7052
+ this.loadUserMedia();
7053
+ }, this.options.timeouts.userMedia);
7054
+ }
7055
+ else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
7042
7056
  else {
7043
7057
  this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
7044
7058
  throw error_createError({
@@ -7095,8 +7109,8 @@ class Recorder extends util_Despot {
7095
7109
  ideal: idealHeight
7096
7110
  };
7097
7111
  }
7098
- this.options.logger.debug(`Recorder: our webcam constraints are: ${util_pretty(constraints)}`);
7099
- this.options.logger.debug(`Recorder: available webcam constraints are: ${util_pretty(navigator.mediaDevices.getSupportedConstraints())}`);
7112
+ this.options.logger.debug(util_summarize("Recorder: our webcam constraints are:", constraints));
7113
+ this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
7100
7114
  const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
7101
7115
  streamPromise.then((localStream)=>{
7102
7116
  this.getUserMediaCallback(localStream, params);
@@ -7258,7 +7272,8 @@ class Recorder extends util_Despot {
7258
7272
  limitReached
7259
7273
  });
7260
7274
  this.loop?.complete();
7261
- setTimeout(()=>{
7275
+ this.stopTimeout = window.setTimeout(()=>{
7276
+ this.stopTimeout = void 0;
7262
7277
  this.stopTime = Date.now();
7263
7278
  const videoType = this.replay.getVideoType();
7264
7279
  if (!videoType) throw new Error("Unable to video record when no video type is defined.");
@@ -7307,6 +7322,9 @@ class Recorder extends util_Despot {
7307
7322
  this.reset();
7308
7323
  this.clearUserMediaTimeout();
7309
7324
  this.clearConnectionTimeout();
7325
+ this.clearRetryTimeout();
7326
+ this.clearStopTimeout();
7327
+ this.stopPings();
7310
7328
  this.connecting = false;
7311
7329
  if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
7312
7330
  if (this.submitting) ;
@@ -7329,12 +7347,17 @@ class Recorder extends util_Despot {
7329
7347
  }
7330
7348
  }
7331
7349
  clearUserMediaTimeout() {
7332
- if (this.userMediaTimeout) {
7350
+ if (void 0 !== this.userMediaTimeout) {
7333
7351
  this.options.logger.debug("Recorder: clearUserMediaTimeout()");
7334
7352
  window.clearTimeout(this.userMediaTimeout);
7335
7353
  this.userMediaTimeout = void 0;
7336
7354
  }
7337
7355
  }
7356
+ clearStopTimeout() {
7357
+ if (void 0 === this.stopTimeout) return;
7358
+ window.clearTimeout(this.stopTimeout);
7359
+ this.stopTimeout = void 0;
7360
+ }
7338
7361
  validate() {
7339
7362
  return this.connected && void 0 === this.canvas;
7340
7363
  }
@@ -7710,7 +7733,7 @@ class Recorder extends util_Despot {
7710
7733
  return this.userMediaLoaded;
7711
7734
  }
7712
7735
  constructor(visuals, replay, options){
7713
- super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
7736
+ super("Recorder", options), recorder_define_property(this, "visuals", void 0), recorder_define_property(this, "replay", void 0), recorder_define_property(this, "loop", void 0), recorder_define_property(this, "originalAnimationFrameObject", void 0), recorder_define_property(this, "samplesCount", 0), recorder_define_property(this, "framesCount", 0), recorder_define_property(this, "recordingStats", void 0), recorder_define_property(this, "confirmedFrameNumber", 0), recorder_define_property(this, "confirmedSampleNumber", 0), recorder_define_property(this, "recorderElement", void 0), recorder_define_property(this, "userMedia", void 0), recorder_define_property(this, "userMediaTimeout", void 0), recorder_define_property(this, "retryTimeout", void 0), recorder_define_property(this, "connectionTimeout", void 0), recorder_define_property(this, "stopTimeout", void 0), recorder_define_property(this, "frameProgress", void 0), recorder_define_property(this, "sampleProgress", void 0), recorder_define_property(this, "canvas", void 0), recorder_define_property(this, "ctx", void 0), recorder_define_property(this, "userMediaLoaded", void 0), recorder_define_property(this, "userMediaLoading", false), recorder_define_property(this, "submitting", false), recorder_define_property(this, "unloaded", void 0), recorder_define_property(this, "stopTime", void 0), recorder_define_property(this, "stream", void 0), recorder_define_property(this, "connecting", false), recorder_define_property(this, "connected", false), recorder_define_property(this, "connectionFailed", false), recorder_define_property(this, "blocking", false), recorder_define_property(this, "built", false), recorder_define_property(this, "key", void 0), recorder_define_property(this, "waitingTime", void 0), recorder_define_property(this, "connectingStartedAt", void 0), recorder_define_property(this, "lastCloseEvent", void 0), recorder_define_property(this, "lastSocketError", void 0), recorder_define_property(this, "pingInterval", void 0), recorder_define_property(this, "frame", void 0), recorder_define_property(this, "recordingBuffer", void 0), recorder_define_property(this, "facingMode", void 0);
7714
7737
  this.visuals = visuals;
7715
7738
  this.replay = replay;
7716
7739
  this.facingMode = options.video.facingMode;
@@ -8351,18 +8374,11 @@ class Container extends util_Despot {
8351
8374
  }
8352
8375
  initEvents(playerOnly = false) {
8353
8376
  this.options.logger.debug(`Container: initEvents (playerOnly = ${playerOnly})`);
8354
- if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", ()=>{
8355
- if (!this.built) return;
8356
- this.emit("WINDOW_RESIZE", "container");
8357
- });
8358
- if (this.options.enableAutoUnload) window.addEventListener("beforeunload", (e)=>{
8359
- this.unload({
8360
- e
8361
- });
8362
- }, {
8377
+ if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", this.handleWindowResize);
8378
+ if (this.options.enableAutoUnload) window.addEventListener("beforeunload", this.handleBeforeUnload, {
8363
8379
  once: true
8364
8380
  });
8365
- if (!playerOnly) this.visibility.onChange((visible)=>{
8381
+ if (!playerOnly) this.stopListeningToVisibility = this.visibility.onChange((visible)=>{
8366
8382
  if (this.built) if (visible) {
8367
8383
  if (isAutoPauseEnabled(this.options) && this.isCountingDown()) this.resume();
8368
8384
  this.emit("VISIBLE");
@@ -8372,19 +8388,7 @@ class Container extends util_Despot {
8372
8388
  }
8373
8389
  });
8374
8390
  if (this.options.enableSpace) {
8375
- if (!playerOnly) window.addEventListener("keydown", (e)=>{
8376
- const element = e.target;
8377
- const tagName = element.tagName;
8378
- const isEditable = element.isContentEditable || "true" === element.contentEditable;
8379
- if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase()) {
8380
- const code = e.code;
8381
- if ("Space" === code) {
8382
- e.preventDefault();
8383
- if (this.options.enablePause) this.visuals.pauseOrResume();
8384
- else this.visuals.recordOrStop();
8385
- }
8386
- }
8387
- });
8391
+ if (!playerOnly) window.addEventListener("keydown", this.handleKeyDown);
8388
8392
  }
8389
8393
  this.on("ERROR", (params)=>{
8390
8394
  this.processError(params);
@@ -8421,6 +8425,13 @@ class Container extends util_Despot {
8421
8425
  }
8422
8426
  this.endWaiting();
8423
8427
  }
8428
+ removeBrowserEventListeners() {
8429
+ window.removeEventListener("resize", this.handleWindowResize);
8430
+ window.removeEventListener("beforeunload", this.handleBeforeUnload);
8431
+ window.removeEventListener("keydown", this.handleKeyDown);
8432
+ this.stopListeningToVisibility?.();
8433
+ this.stopListeningToVisibility = void 0;
8434
+ }
8424
8435
  hideMySelf() {
8425
8436
  html_hideElement(this.containerElement);
8426
8437
  }
@@ -8487,6 +8498,7 @@ class Container extends util_Despot {
8487
8498
  exc
8488
8499
  });
8489
8500
  } finally{
8501
+ this.removeBrowserEventListeners();
8490
8502
  this.removeAllListeners();
8491
8503
  this.built = this.submitted = false;
8492
8504
  }
@@ -8756,7 +8768,22 @@ class Container extends util_Despot {
8756
8768
  this.visuals.setLimitSeconds(limitSeconds);
8757
8769
  }
8758
8770
  constructor(options){
8759
- super("Container", options), container_define_property(this, "visibility", document_visibility()), container_define_property(this, "htmlElement", document.querySelector("html")), container_define_property(this, "visuals", void 0), container_define_property(this, "buttons", void 0), container_define_property(this, "resource", void 0), container_define_property(this, "form", void 0), container_define_property(this, "hasError", false), container_define_property(this, "submitted", false), container_define_property(this, "lastValidation", false), container_define_property(this, "containerElement", void 0), container_define_property(this, "built", false);
8771
+ super("Container", options), container_define_property(this, "visibility", document_visibility()), container_define_property(this, "htmlElement", document.querySelector("html")), container_define_property(this, "visuals", void 0), container_define_property(this, "buttons", void 0), container_define_property(this, "resource", void 0), container_define_property(this, "form", void 0), container_define_property(this, "hasError", false), container_define_property(this, "submitted", false), container_define_property(this, "lastValidation", false), container_define_property(this, "containerElement", void 0), container_define_property(this, "built", false), container_define_property(this, "stopListeningToVisibility", void 0), container_define_property(this, "handleWindowResize", ()=>{
8772
+ if (this.built) this.emit("WINDOW_RESIZE", "container");
8773
+ }), container_define_property(this, "handleBeforeUnload", (e)=>{
8774
+ this.unload({
8775
+ e
8776
+ });
8777
+ }), container_define_property(this, "handleKeyDown", (e)=>{
8778
+ const element = e.target;
8779
+ const tagName = element.tagName;
8780
+ const isEditable = element.isContentEditable || "true" === element.contentEditable;
8781
+ if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase() && "Space" === e.code) {
8782
+ e.preventDefault();
8783
+ if (this.options.enablePause) this.visuals.pauseOrResume();
8784
+ else this.visuals.recordOrStop();
8785
+ }
8786
+ });
8760
8787
  this.visuals = new wrappers_visuals(this, options);
8761
8788
  this.buttons = new buttons(this, options);
8762
8789
  this.resource = new src_resource(options);
@@ -28,6 +28,10 @@ declare class Container extends Despot {
28
28
  private lastValidation;
29
29
  private containerElement?;
30
30
  private built;
31
+ private stopListeningToVisibility?;
32
+ private readonly handleWindowResize;
33
+ private readonly handleBeforeUnload;
34
+ private readonly handleKeyDown;
31
35
  constructor(options: VideomailClientOptions);
32
36
  private buildChildren;
33
37
  build(buildOptions?: BuildOptions): HTMLElement | null | undefined;
@@ -39,6 +43,7 @@ declare class Container extends Despot {
39
43
  private correctDimensions;
40
44
  private removeDimensions;
41
45
  private unloadChildren;
46
+ private removeBrowserEventListeners;
42
47
  private hideMySelf;
43
48
  private submitVideomail;
44
49
  limitWidth(width?: number): import("../types/dimension.js").Dimension | undefined;
@@ -26,6 +26,7 @@ declare class Recorder extends Despot {
26
26
  private userMediaTimeout?;
27
27
  private retryTimeout?;
28
28
  private connectionTimeout?;
29
+ private stopTimeout?;
29
30
  private frameProgress?;
30
31
  private sampleProgress?;
31
32
  private canvas?;
@@ -59,6 +60,7 @@ declare class Recorder extends Despot {
59
60
  private onUserMediaReady;
60
61
  private clearRetryTimeout;
61
62
  private clearConnectionTimeout;
63
+ private isOnline;
62
64
  private failConnection;
63
65
  private calculateFrameProgress;
64
66
  private calculateSampleProgress;
@@ -88,6 +90,7 @@ declare class Recorder extends Despot {
88
90
  unload(params?: UnloadParams): void;
89
91
  reset(): void;
90
92
  private clearUserMediaTimeout;
93
+ private clearStopTimeout;
91
94
  validate(): boolean;
92
95
  isReady(): boolean | undefined;
93
96
  pause(params?: PauseParams): void;
package/dist/umd/index.js CHANGED
@@ -10978,7 +10978,7 @@
10978
10978
  var client = __webpack_require__("Q");
10979
10979
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
10980
10980
  var package_namespaceObject = {
10981
- rE: "15.7.19"
10981
+ rE: "15.8.1"
10982
10982
  };
10983
10983
  function isAudioEnabled(options) {
10984
10984
  return Boolean(options.audio.enabled);
@@ -19062,7 +19062,8 @@
19062
19062
  }
19063
19063
  hasInvalidDimensions() {
19064
19064
  if (!this.rawVisualUserMedia) return false;
19065
- return this.rawVisualUserMedia.videoWidth < 3 || this.rawVisualUserMedia.videoHeight < 3;
19065
+ const { videoWidth, videoHeight } = this.rawVisualUserMedia;
19066
+ return videoWidth > 0 && videoWidth < 3 || videoHeight > 0 && videoHeight < 3;
19066
19067
  }
19067
19068
  logEvent(eventType, params) {
19068
19069
  this.options.logger.debug(`UserMedia: ... ${EVENT_ASCII} event ${eventType}: ${util_pretty(params)}`);
@@ -19332,6 +19333,7 @@
19332
19333
  userMediaTimeout;
19333
19334
  retryTimeout;
19334
19335
  connectionTimeout;
19336
+ stopTimeout;
19335
19337
  frameProgress;
19336
19338
  sampleProgress;
19337
19339
  canvas;
@@ -19406,13 +19408,16 @@
19406
19408
  }
19407
19409
  }
19408
19410
  sendPings() {
19411
+ this.stopPings();
19409
19412
  this.pingInterval = window.setInterval(()=>{
19410
19413
  this.options.logger.debug("Recorder: pinging...");
19411
19414
  this.writeStream(Buffer.from(""));
19412
19415
  }, this.options.timeouts.pingInterval);
19413
19416
  }
19414
19417
  stopPings() {
19415
- clearInterval(this.pingInterval);
19418
+ if (void 0 === this.pingInterval) return;
19419
+ window.clearInterval(this.pingInterval);
19420
+ this.pingInterval = void 0;
19416
19421
  }
19417
19422
  onAudioSample(audioSample) {
19418
19423
  this.samplesCount++;
@@ -19443,24 +19448,27 @@
19443
19448
  }
19444
19449
  }
19445
19450
  clearRetryTimeout() {
19446
- if (!this.retryTimeout) return;
19451
+ if (void 0 === this.retryTimeout) return;
19447
19452
  this.options.logger.debug("Recorder: clearRetryTimeout()");
19448
19453
  window.clearTimeout(this.retryTimeout);
19449
19454
  this.retryTimeout = void 0;
19450
19455
  }
19451
19456
  clearConnectionTimeout() {
19452
- if (!this.connectionTimeout) return;
19457
+ if (void 0 === this.connectionTimeout) return;
19453
19458
  this.options.logger.debug("Recorder: clearConnectionTimeout()");
19454
19459
  window.clearTimeout(this.connectionTimeout);
19455
19460
  this.connectionTimeout = void 0;
19456
19461
  }
19462
+ isOnline() {
19463
+ return navigator.onLine;
19464
+ }
19457
19465
  failConnection(params) {
19458
19466
  if (this.connectionFailed || this.connected || this.unloaded) return;
19459
19467
  this.connectionFailed = true;
19460
19468
  this.connecting = false;
19461
19469
  this.clearConnectionTimeout();
19462
19470
  const { url2Connect, cause } = params;
19463
- const online = navigator.onLine;
19471
+ const online = this.isOnline();
19464
19472
  const elapsedMs = this.connectingStartedAt ? Date.now() - this.connectingStartedAt : void 0;
19465
19473
  const closeEvent = this.lastCloseEvent;
19466
19474
  const socketError = this.lastSocketError;
@@ -19649,7 +19657,10 @@
19649
19657
  if (this.stream) {
19650
19658
  const connectionTimeoutMs = this.options.timeouts.connection;
19651
19659
  this.connectionTimeout = window.setTimeout(()=>{
19652
- this.failConnection({
19660
+ if (this.isOnline() && this.isUserMediaLoaded()) {
19661
+ this.options.logger.debug(`${PIPE_SYMBOL}Reconnecting due to connection timeout.`);
19662
+ this.initSocket();
19663
+ } else this.failConnection({
19653
19664
  url2Connect,
19654
19665
  cause: "timeout"
19655
19666
  });
@@ -19774,19 +19785,23 @@
19774
19785
  const characteristics = this.userMedia?.getCharacteristics();
19775
19786
  this.options.logger.debug(`Recorder: userMediaErrorCallback(), name: ${err.name}, message: ${err.message} and Webcam characteristics: ${characteristics ? util_pretty(characteristics) : "none"}`);
19776
19787
  const errorListeners = this.getListeners("ERROR");
19777
- if (errorListeners?.length) {
19778
- if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
19779
- const videomailError = error_createError({
19780
- err,
19781
- options: this.options,
19782
- usedConstraints
19783
- });
19784
- this.emit("ERROR", {
19785
- err: videomailError
19786
- });
19787
- } else this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
19788
- this.retryTimeout = window.setTimeout(this.initSocket.bind(this), this.options.timeouts.userMedia);
19789
- } else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
19788
+ if (errorListeners?.length) if (err.name !== error_VideomailError.MEDIA_DEVICE_NOT_SUPPORTED) {
19789
+ const videomailError = error_createError({
19790
+ err,
19791
+ options: this.options,
19792
+ usedConstraints
19793
+ });
19794
+ this.emit("ERROR", {
19795
+ err: videomailError
19796
+ });
19797
+ } else {
19798
+ this.options.logger.debug(`Recorder: ignore user media error ${util_pretty(err)}`);
19799
+ this.retryTimeout = window.setTimeout(()=>{
19800
+ this.retryTimeout = void 0;
19801
+ this.loadUserMedia();
19802
+ }, this.options.timeouts.userMedia);
19803
+ }
19804
+ else if (this.unloaded) this.options.logger.debug(`Recorder: already unloaded. Not going to throw error ${util_pretty(err)}`);
19790
19805
  else {
19791
19806
  this.options.logger.debug(`Recorder: no error listeners attached but throwing error ${util_pretty(err)}`);
19792
19807
  throw error_createError({
@@ -19843,8 +19858,8 @@
19843
19858
  ideal: idealHeight
19844
19859
  };
19845
19860
  }
19846
- this.options.logger.debug(`Recorder: our webcam constraints are: ${util_pretty(constraints)}`);
19847
- this.options.logger.debug(`Recorder: available webcam constraints are: ${util_pretty(navigator.mediaDevices.getSupportedConstraints())}`);
19861
+ this.options.logger.debug(util_summarize("Recorder: our webcam constraints are:", constraints));
19862
+ this.options.logger.debug(util_summarize("Recorder: available webcam constraints are:", navigator.mediaDevices.getSupportedConstraints()));
19848
19863
  const streamPromise = navigator.mediaDevices.getUserMedia(constraints);
19849
19864
  streamPromise.then((localStream)=>{
19850
19865
  this.getUserMediaCallback(localStream, params);
@@ -20006,7 +20021,8 @@
20006
20021
  limitReached
20007
20022
  });
20008
20023
  this.loop?.complete();
20009
- setTimeout(()=>{
20024
+ this.stopTimeout = window.setTimeout(()=>{
20025
+ this.stopTimeout = void 0;
20010
20026
  this.stopTime = Date.now();
20011
20027
  const videoType = this.replay.getVideoType();
20012
20028
  if (!videoType) throw new Error("Unable to video record when no video type is defined.");
@@ -20055,6 +20071,9 @@
20055
20071
  this.reset();
20056
20072
  this.clearUserMediaTimeout();
20057
20073
  this.clearConnectionTimeout();
20074
+ this.clearRetryTimeout();
20075
+ this.clearStopTimeout();
20076
+ this.stopPings();
20058
20077
  this.connecting = false;
20059
20078
  if (this.userMedia) this.userMedia.unloadRemainingEventListeners();
20060
20079
  if (this.submitting) ;
@@ -20077,12 +20096,17 @@
20077
20096
  }
20078
20097
  }
20079
20098
  clearUserMediaTimeout() {
20080
- if (this.userMediaTimeout) {
20099
+ if (void 0 !== this.userMediaTimeout) {
20081
20100
  this.options.logger.debug("Recorder: clearUserMediaTimeout()");
20082
20101
  window.clearTimeout(this.userMediaTimeout);
20083
20102
  this.userMediaTimeout = void 0;
20084
20103
  }
20085
20104
  }
20105
+ clearStopTimeout() {
20106
+ if (void 0 === this.stopTimeout) return;
20107
+ window.clearTimeout(this.stopTimeout);
20108
+ this.stopTimeout = void 0;
20109
+ }
20086
20110
  validate() {
20087
20111
  return this.connected && void 0 === this.canvas;
20088
20112
  }
@@ -21011,6 +21035,25 @@
21011
21035
  lastValidation = false;
21012
21036
  containerElement;
21013
21037
  built = false;
21038
+ stopListeningToVisibility;
21039
+ handleWindowResize = ()=>{
21040
+ if (this.built) this.emit("WINDOW_RESIZE", "container");
21041
+ };
21042
+ handleBeforeUnload = (e)=>{
21043
+ this.unload({
21044
+ e
21045
+ });
21046
+ };
21047
+ handleKeyDown = (e)=>{
21048
+ const element = e.target;
21049
+ const tagName = element.tagName;
21050
+ const isEditable = element.isContentEditable || "true" === element.contentEditable;
21051
+ if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase() && "Space" === e.code) {
21052
+ e.preventDefault();
21053
+ if (this.options.enablePause) this.visuals.pauseOrResume();
21054
+ else this.visuals.recordOrStop();
21055
+ }
21056
+ };
21014
21057
  constructor(options){
21015
21058
  super("Container", options);
21016
21059
  this.visuals = new wrappers_visuals(this, options);
@@ -21093,18 +21136,11 @@
21093
21136
  }
21094
21137
  initEvents(playerOnly = false) {
21095
21138
  this.options.logger.debug(`Container: initEvents (playerOnly = ${playerOnly})`);
21096
- if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", ()=>{
21097
- if (!this.built) return;
21098
- this.emit("WINDOW_RESIZE", "container");
21099
- });
21100
- if (this.options.enableAutoUnload) window.addEventListener("beforeunload", (e)=>{
21101
- this.unload({
21102
- e
21103
- });
21104
- }, {
21139
+ if (this.options.recalculateDimensionsOnWindowResize) window.addEventListener("resize", this.handleWindowResize);
21140
+ if (this.options.enableAutoUnload) window.addEventListener("beforeunload", this.handleBeforeUnload, {
21105
21141
  once: true
21106
21142
  });
21107
- if (!playerOnly) this.visibility.onChange((visible)=>{
21143
+ if (!playerOnly) this.stopListeningToVisibility = this.visibility.onChange((visible)=>{
21108
21144
  if (this.built) if (visible) {
21109
21145
  if (isAutoPauseEnabled(this.options) && this.isCountingDown()) this.resume();
21110
21146
  this.emit("VISIBLE");
@@ -21114,19 +21150,7 @@
21114
21150
  }
21115
21151
  });
21116
21152
  if (this.options.enableSpace) {
21117
- if (!playerOnly) window.addEventListener("keydown", (e)=>{
21118
- const element = e.target;
21119
- const tagName = element.tagName;
21120
- const isEditable = element.isContentEditable || "true" === element.contentEditable;
21121
- if (!isEditable && tagName && "INPUT" !== tagName.toUpperCase() && "TEXTAREA" !== tagName.toUpperCase()) {
21122
- const code = e.code;
21123
- if ("Space" === code) {
21124
- e.preventDefault();
21125
- if (this.options.enablePause) this.visuals.pauseOrResume();
21126
- else this.visuals.recordOrStop();
21127
- }
21128
- }
21129
- });
21153
+ if (!playerOnly) window.addEventListener("keydown", this.handleKeyDown);
21130
21154
  }
21131
21155
  this.on("ERROR", (params)=>{
21132
21156
  this.processError(params);
@@ -21163,6 +21187,13 @@
21163
21187
  }
21164
21188
  this.endWaiting();
21165
21189
  }
21190
+ removeBrowserEventListeners() {
21191
+ window.removeEventListener("resize", this.handleWindowResize);
21192
+ window.removeEventListener("beforeunload", this.handleBeforeUnload);
21193
+ window.removeEventListener("keydown", this.handleKeyDown);
21194
+ this.stopListeningToVisibility?.();
21195
+ this.stopListeningToVisibility = void 0;
21196
+ }
21166
21197
  hideMySelf() {
21167
21198
  html_hideElement(this.containerElement);
21168
21199
  }
@@ -21229,6 +21260,7 @@
21229
21260
  exc
21230
21261
  });
21231
21262
  } finally{
21263
+ this.removeBrowserEventListeners();
21232
21264
  this.removeAllListeners();
21233
21265
  this.built = this.submitted = false;
21234
21266
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "videomail-client",
3
- "version": "15.7.19",
3
+ "version": "15.8.1",
4
4
  "description": "A wicked npm package to record videos directly in the browser, for Deaf and Sign Language!",
5
5
  "keywords": [
6
6
  "webcam",
@@ -88,11 +88,11 @@
88
88
  "@rsbuild/plugin-node-polyfill": "1.4.6",
89
89
  "@rsbuild/plugin-stylus": "2.0.1",
90
90
  "@rsdoctor/rspack-plugin": "1.6.4",
91
- "@rslib/core": "1.0.2",
92
- "@storybook/addon-a11y": "10.6.0",
93
- "@storybook/addon-docs": "10.6.0",
94
- "@storybook/addon-links": "10.6.0",
95
- "@storybook/html": "10.6.0",
91
+ "@rslib/core": "1.0.3",
92
+ "@storybook/addon-a11y": "10.6.1",
93
+ "@storybook/addon-docs": "10.6.1",
94
+ "@storybook/addon-links": "10.6.1",
95
+ "@storybook/html": "10.6.1",
96
96
  "@tsconfig/node26": "26.0.1",
97
97
  "@tsconfig/strictest": "2.0.8",
98
98
  "@types/defined": "1.0.2",
@@ -121,7 +121,7 @@
121
121
  "prettier-plugin-packagejson": "3.0.2",
122
122
  "prettier-plugin-sh": "0.20.2",
123
123
  "release-it": "21.1.0",
124
- "storybook": "10.6.0",
124
+ "storybook": "10.6.1",
125
125
  "storybook-html-rsbuild": "3.6.0",
126
126
  "type-fest": "5.10.0",
127
127
  "typescript": "6.0.3",