eb-player 2.5.3 → 2.5.4

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.
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Runtime feature floor of the player.
3
+ *
4
+ * The bundle's *syntax* floor is ES2017 (see scripts/check-syntax-floor.ts),
5
+ * which parses on Chrome 55+, Safari 10.1+ and Firefox 52+. Some of those
6
+ * engines still lack runtime APIs the player cannot work without:
7
+ *
8
+ * - Proxy — the reactive PlayerState store (Chrome 49, Safari 10)
9
+ * - AbortController — every subscription/listener cleanup (Chrome 66,
10
+ * Safari 12.1, Firefox 57)
11
+ *
12
+ * On such a browser `start()` used to throw a bare ReferenceError from deep
13
+ * inside PlayerController's constructor, leaving the integrator's container
14
+ * as an empty white box. This module lets start() detect the gap up front
15
+ * and show a readable message instead, using only pre-ES2015 DOM APIs.
16
+ */
17
+ export declare const REQUIRED_RUNTIME_FEATURES: readonly ["Proxy", "AbortController"];
18
+ /**
19
+ * Returns the names of the required runtime features that are not
20
+ * constructors on `scope` (defaults to `window`).
21
+ */
22
+ export declare function findMissingRuntimeFeatures(scope?: Record<string, unknown>): string[];
23
+ /**
24
+ * Replaces the container's content with the skin's error overlay markup
25
+ * (same class names as ErrorMessage, so the shipped CSS styles it) carrying
26
+ * the translated "browser not supported" text. Plain DOM calls only: this
27
+ * runs precisely on the browsers where lit-html/PlayerState cannot.
28
+ */
29
+ export declare function renderUnsupportedBrowser(container: HTMLElement, lang?: string): void;
@@ -26,6 +26,14 @@ export declare abstract class BaseEngine extends EngineStateSync {
26
26
  */
27
27
  protected loadSourceUrl: string;
28
28
  private watchdog;
29
+ /**
30
+ * Every native video listener bound by bindVideoEvents(), so detach() can
31
+ * remove them itself. They are also registered with `{ signal }`, but
32
+ * Chromium < 90, Safari < 15 and Firefox < 86 silently ignore that option:
33
+ * on those engines the listeners outlived destroy() and kept writing a
34
+ * disposed PlayerState on every timeupdate (Sentry FORJA-FRONTWEB-5B9/5BA).
35
+ */
36
+ private videoListeners;
29
37
  /**
30
38
  * Promise that resolves when the engine driver (hls.js/dash.js) is created
31
39
  * and ready for integration (e.g., P2P SDK). Resolved inside onAttach().
@@ -49,6 +57,11 @@ export declare abstract class BaseEngine extends EngineStateSync {
49
57
  */
50
58
  setLoadSource(src: string): void;
51
59
  protected bindVideoEvents(video: HTMLVideoElement, state: PlayerState, signal: AbortSignal): void;
60
+ /**
61
+ * Removes every listener bound by bindVideoEvents() — the explicit half of
62
+ * the cleanup that `{ signal }` was supposed to do on its own.
63
+ */
64
+ private unbindVideoEvents;
52
65
  protected abstract recoverFromStall(attempt: number): void;
53
66
  protected abstract onAttach(): Promise<void> | void;
54
67
  protected abstract onDetach(): void;
@@ -63,6 +63,16 @@ export declare abstract class BaseComponent {
63
63
  /**
64
64
  * Renders the component into this.el using lit-html.
65
65
  * No-op if el is null (e.g., after disconnect()).
66
+ *
67
+ * A render that throws is contained: lit-html keeps its parts alive through
68
+ * comment markers inside the component's subtree, and a DOM rewriter
69
+ * outside the player (page translation, an extension) that rebuilds that
70
+ * markup without the markers breaks the part for good — every later render
71
+ * throws the same `this._$AA.nextSibling is null` and, with a component
72
+ * re-rendering on each state tick, that is thousands of identical errors
73
+ * per session (Sentry FORJA-FRONTWEB-5EZ..5F1). The failure is logged once,
74
+ * the view is unsubscribed from state/bus updates, and render() becomes a
75
+ * no-op. disconnect() stays safe to call afterwards.
66
76
  */
67
77
  protected render(): void;
68
78
  }
@@ -4,17 +4,27 @@ import { BaseComponent } from '../base-component';
4
4
  * Volume control with mute toggle button and draggable slider.
5
5
  *
6
6
  * - Mute button emits 'mute-toggle'
7
- * - Slider uses Pointer Events API (pointerdown/pointermove/pointerup)
7
+ * - Slider uses Pointer Events API (pointerdown/pointermove/pointerup/pointercancel)
8
8
  * - Slider fill width reflects current volume (0% to 100%)
9
9
  * - When muted, fill shows 0% visually
10
+ *
11
+ * The document-level drag listeners are stable instance methods, never
12
+ * per-drag closures: a second pointerdown landing during a drag (a second
13
+ * finger on a phone) used to overwrite the stored closure, so the first
14
+ * drag's listeners could never be removed again and kept calling
15
+ * eventToVolume() against a track rect that pointerup had already nulled
16
+ * (Sentry FORJA-FRONTWEB-5E3/5E4). With one function reference per event
17
+ * type, addEventListener is idempotent and removeEventListener always pairs.
10
18
  */
11
19
  export declare class VolumeControl extends BaseComponent {
12
20
  private trackRect;
13
- private onPointerMove;
14
- private onPointerUp;
21
+ private readonly onDocumentPointerMove;
22
+ private readonly onDocumentPointerUp;
23
+ private readonly onDocumentPointerCancel;
15
24
  protected onConnect(): void;
16
25
  private eventToVolume;
17
26
  private handlePointerDown;
27
+ private endDrag;
18
28
  private getVolumeIcon;
19
29
  protected template(): TemplateResult;
20
30
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Call `video.play()` and swallow its rejection.
3
+ *
4
+ * play() returns a promise that rejects with `AbortError` whenever pause() —
5
+ * or a new load — interrupts the pending play request. That is the normal
6
+ * outcome of a fast pause after play, an ad break, a cast hand-over or a
7
+ * source switch, never something the caller can act on, and left unhandled
8
+ * it reaches the page as an unhandled promise rejection (Sentry issues 18
9
+ * and W, ~420 users/day on forja.ma). Browsers predating the promise return
10
+ * (and jsdom) return undefined, so the catch is only attached when there is
11
+ * something to attach it to.
12
+ */
13
+ /** Anything with a media-element-shaped play(): HTMLVideoElement, or the poster loop's minimal media handle. */
14
+ export interface Playable {
15
+ play(): unknown;
16
+ }
17
+ export declare function playQuietly(video: Playable): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eb-player",
3
- "version": "2.5.3",
3
+ "version": "2.5.4",
4
4
  "packageManager": "pnpm@11.24.0",
5
5
  "scripts": {
6
6
  "generate-demo": "pnpm generate --brand default --variant demo && cp dist/players/default/default.js test_player/src/demo.js",
@@ -12,13 +12,14 @@
12
12
  "lint": "eslint src/ test/",
13
13
  "lint:fix": "eslint src/ test/ --fix",
14
14
  "typecheck": "tsc --noEmit",
15
- "build": "NODE_ENV=production rollup -c rollup.config.ts --configPlugin typescript",
16
- "postbuild": "cp dist/build/eb-player.css dist/ && cp src/core/css/theme-*.css dist/build/ && cp src/core/css/theme-*.css dist/ && tsx scripts/size-check.ts && tsx scripts/check-no-vue.ts && tsx scripts/check-api-surface.ts",
15
+ "build": "NODE_ENV=production rollup -c rollup.config.ts --configPlugin \"typescript={tsconfig:'tsconfig.rollup.json'}\"",
16
+ "postbuild": "cp dist/build/eb-player.css dist/ && cp src/core/css/theme-*.css dist/build/ && cp src/core/css/theme-*.css dist/ && tsx scripts/size-check.ts && tsx scripts/check-no-vue.ts && tsx scripts/check-api-surface.ts && tsx scripts/check-syntax-floor.ts",
17
17
  "dev": "node --import tsx scripts/dev-server.ts",
18
18
  "generate": "node --import tsx scripts/generate.ts",
19
19
  "size-check": "tsx scripts/size-check.ts",
20
20
  "check-no-vue": "tsx scripts/check-no-vue.ts",
21
21
  "check-api-surface": "tsx scripts/check-api-surface.ts",
22
+ "check-syntax-floor": "tsx scripts/check-syntax-floor.ts",
22
23
  "prepare": "husky"
23
24
  },
24
25
  "devDependencies": {
@@ -30,6 +31,7 @@
30
31
  "@rollup/plugin-virtual": "^3.0.2",
31
32
  "@types/node": "^26.4.0",
32
33
  "@vitest/coverage-v8": "^4.1.8",
34
+ "acorn": "^8.16.0",
33
35
  "concurrently": "^10.0.3",
34
36
  "eslint": "^10.4.1",
35
37
  "eslint-plugin-lit": "^2.3.1",