Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
d017764
Add cover helper
JayPanoz Feb 23, 2026
7927815
Init Navigator
JayPanoz Feb 23, 2026
14ed7e7
Add skip props in abstract class
JayPanoz Feb 23, 2026
3b0b327
Hepers for start/end
JayPanoz Feb 24, 2026
586578c
Correct audio preferences
JayPanoz Feb 24, 2026
c497333
More docs + correcting methods
JayPanoz Feb 24, 2026
7af3ffd
Merge branch 'develop' into audio-navigator
JayPanoz Feb 24, 2026
d56262b
Merge branch 'develop' into audio-navigator
JayPanoz Feb 24, 2026
8065108
Missing export for prefs
JayPanoz Mar 10, 2026
5340674
Consistency in config
JayPanoz Mar 10, 2026
e7c4095
Fixes for media session
JayPanoz Mar 11, 2026
7a3721f
Correct time location
JayPanoz Mar 11, 2026
43c04e4
Fix locations
JayPanoz Mar 11, 2026
c0ff2b1
Fix bound handlers
JayPanoz Mar 16, 2026
d96126d
Fix web audio and events
JayPanoz Mar 16, 2026
0b10bb5
Ping positionChanged on init
JayPanoz Mar 17, 2026
eb21cb2
Handle positionChanged on seek
JayPanoz Mar 17, 2026
eb55a4a
onSeeking listener
JayPanoz Mar 17, 2026
1ca5fd4
Make audio navigator consistent
JayPanoz Mar 17, 2026
dbb27cf
Handle buffering
JayPanoz Mar 17, 2026
ffdbcbd
Revert "Handle buffering"
JayPanoz Mar 17, 2026
5434177
Handle CORS missing header in Engine
JayPanoz Mar 17, 2026
18befb1
Correct WebPubPreferencesEditor
JayPanoz Mar 17, 2026
0cf2707
Remove unused import
JayPanoz Mar 17, 2026
3b503ce
Correct volume and rate settings
JayPanoz Mar 18, 2026
4260e01
Update default pref values
JayPanoz Mar 18, 2026
7c06058
Add seekable event
JayPanoz Mar 19, 2026
6d90a17
Correct autoPlay
JayPanoz Mar 19, 2026
93362de
Improve pref API types
JayPanoz Mar 19, 2026
5f21edb
Correct audio docs
JayPanoz Mar 20, 2026
82bd977
Bump version to beta for debugging purposes
JayPanoz Mar 20, 2026
4e218a2
Add protection and peripherals
JayPanoz Mar 22, 2026
675d242
Mimetypes support check
JayPanoz Mar 22, 2026
243c520
Bump version
JayPanoz Mar 22, 2026
c33466d
Correct goLink in audio
JayPanoz Mar 22, 2026
58b556d
Add artwork in media session
JayPanoz Mar 23, 2026
1e2319d
Update playback rate step
JayPanoz Mar 23, 2026
15d3616
Bump version for new beta package
JayPanoz Mar 23, 2026
fe6454b
Fix preferences on instantiation
JayPanoz Mar 23, 2026
bb003fa
fix onEnded continuous play
JayPanoz Mar 24, 2026
a065899
Handle quick fire of nav methods
JayPanoz Mar 24, 2026
37ea849
Bump version
JayPanoz Mar 24, 2026
8b1aa73
Rework engine + pool interaction
JayPanoz Mar 24, 2026
cce5f97
Merge branch 'develop' into audio-navigator
JayPanoz Mar 24, 2026
2337199
Init timeline API for Audio
JayPanoz Mar 24, 2026
9282602
Correct timeline current match
JayPanoz Mar 25, 2026
3cbd3bd
Update previous/next
JayPanoz Mar 25, 2026
102e887
Correct printing check
JayPanoz Mar 28, 2026
e13d2b1
Bump playbackRate max
JayPanoz Mar 30, 2026
778b18a
Revamp timeline
JayPanoz Mar 31, 2026
632e150
Correct stalling when not playing
JayPanoz Apr 2, 2026
3afacfd
Update comments and docs
JayPanoz Apr 2, 2026
6f38aa5
Bump versions
JayPanoz Apr 2, 2026
4c0e280
Fix linkFor
JayPanoz Apr 3, 2026
61f63d7
Remote Playback
JayPanoz Apr 3, 2026
6d2ba54
Bump navigator
JayPanoz Apr 3, 2026
9c65c70
Remote playback fixes
JayPanoz Apr 8, 2026
ec4153d
Update Readium CSS
JayPanoz Apr 9, 2026
8b7fc46
Update media session on timelineItem change
JayPanoz Apr 13, 2026
6357047
Merge branch 'develop' into audio-navigator
JayPanoz Apr 13, 2026
fc91ed9
Add extensions to new imports
JayPanoz Apr 13, 2026
f1a641b
Correct shared imports
JayPanoz Apr 13, 2026
8f088fa
Fix docstring comment for timeline getter
JayPanoz Apr 13, 2026
6fdc4b3
Fix Timeline service
JayPanoz Apr 13, 2026
0ccdf82
Fix setVolume
JayPanoz Apr 13, 2026
99d5668
Fix activateWebAudio
JayPanoz Apr 13, 2026
8543b6c
Fix trackEnded in docs
JayPanoz Apr 13, 2026
5fe6529
Fix polling issues
JayPanoz Apr 13, 2026
cf54af4
Make all listeners required
JayPanoz Apr 13, 2026
f37103e
Rewrite pitch processor logic
JayPanoz Apr 13, 2026
6a3f57b
Fix Preferences across Navigators
JayPanoz Apr 13, 2026
5c3349c
Correct more audio imports
JayPanoz Apr 13, 2026
16637c9
Correct position in audio Locators
JayPanoz Apr 13, 2026
6326d16
destroy remove unload listener
JayPanoz Apr 13, 2026
b32e023
Correct preservesPitch in setPlaybackRate
JayPanoz Apr 13, 2026
4be6ad6
Test for getCover helper
JayPanoz Apr 13, 2026
2623203
Correct trimToDepth
JayPanoz Apr 13, 2026
3d90391
Correct PitchWorklet for single media element
JayPanoz Apr 13, 2026
3407b51
Href check on changeSrc
JayPanoz Apr 13, 2026
14bef0e
Correct triggering of trackLoaded
JayPanoz Apr 14, 2026
ff6ba0f
Correct volume in WebAudio
JayPanoz Apr 14, 2026
ebcf2a7
tsconfig for shared test
JayPanoz Apr 14, 2026
9918212
Resolve AudioContext lifecycle issues
JayPanoz Apr 14, 2026
9554864
Update autoPlay doc
JayPanoz Apr 14, 2026
abad2d0
Resolve Navigator corner cases
JayPanoz Apr 14, 2026
0f61186
Remove crossorigin instead of empty string
JayPanoz Apr 14, 2026
bd7822a
Correct docs
JayPanoz Apr 14, 2026
013ecfa
Fix remote Playback return type
JayPanoz Apr 14, 2026
dc05ab6
Make sure session artwork src is absolute
JayPanoz Apr 14, 2026
d8549ee
Correct itemStartTime
JayPanoz Apr 14, 2026
66e0465
Correct drop
JayPanoz Apr 14, 2026
cef237a
Bump version
JayPanoz Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions navigator-html-injectables/CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.3.1] – 2026-04-14

### Fixes

- Imports and exports now include file extension ([#205](https://github.com/readium/ts-toolkit/pull/205))

## [2.3.0] – 2026-02-24

### Added
Expand Down
2 changes: 1 addition & 1 deletion navigator-html-injectables/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@readium/navigator-html-injectables",
"version": "2.3.0",
"version": "2.3.1",
"type": "module",
"description": "An embeddable solution for connecting frames of HTML publications with a Readium Navigator",
"author": "readium",
Expand Down
4 changes: 2 additions & 2 deletions navigator-html-injectables/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './comms/index.ts';
export * from './modules/index.ts';
export * from './Loader';
export * from './protection';
export * from './Loader.ts';
export * from './protection/index.ts';
9 changes: 9 additions & 0 deletions navigator-html-injectables/src/modules/Peripherals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,15 @@ export class Peripherals extends Module {
private addDragAndDropPrevention(): void {
if (this.isDragAndDropEnabled || !this.wnd) return;
this.wnd.document.addEventListener("dragstart", this.onDragStart);
this.wnd.document.addEventListener("dragover", this.onDragOver);
this.wnd.document.addEventListener("drop", this.onDrop);
this.isDragAndDropEnabled = true;
}

private removeDragAndDropPrevention(): void {
if (!this.isDragAndDropEnabled || !this.wnd) return;
this.wnd.document.removeEventListener("dragstart", this.onDragStart);
this.wnd.document.removeEventListener("dragover", this.onDragOver);
this.wnd.document.removeEventListener("drop", this.onDrop);
this.isDragAndDropEnabled = false;
}
Expand Down Expand Up @@ -330,6 +332,13 @@ export class Peripherals extends Module {
this.isSelectionMonitoringEnabled = false;
}

private onDragOver = (event: DragEvent) => {
if (this.isDragAndDropEnabled) {
event.preventDefault();
event.stopPropagation();
}
};

private onDragStart = (event: DragEvent) => {
if (this.isDragAndDropEnabled) {
// Drag and drop protection is enabled - prevent it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface SelectionAnalyzerOptions {
historySize: number;
}

import { SELECTION_ANALYZER_CONFIG } from './config';
import { SELECTION_ANALYZER_CONFIG } from './config.ts';

export class SelectionAnalyzer {
private events: SelectionEvent[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
Selector,
TextPositionSelector,
TextQuoteSelector,
} from './api-types';
} from './api-types.ts';
import {
MediaTimeAnchor,
RangeAnchor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
RangeSelector,
TextPositionSelector,
TextQuoteSelector,
} from './api-types';
} from './api-types.ts';
import { matchQuote } from './match-quote';
import { TextRange, TextPosition } from './text-range';
import { nodeFromXPath, xpathFromNode } from './xpath';
Expand Down
11 changes: 11 additions & 0 deletions navigator/CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.4.0] – 2026-04-14

### Added

- Audio Navigator and a `Media Navigator` abstract for media playback navigators
- Expose `Timeline` in Audio Navigator

### Fixed

- Corrects `printProtection` in all Navigators

## [2.3.1] – 2026–03–19

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Handling Publications

To create an instance of `EpubNavigator`, we need a `Publication` that requires a [Readium Web Publication Manifest](https://readium.org/webpub-manifest/).
To create an instance of `Navigator`, we need a `Publication` that requires a [Readium Web Publication Manifest](https://readium.org/webpub-manifest/).

We are using Readium Shared Models to handle all of the following.

Expand Down
180 changes: 180 additions & 0 deletions navigator/docs/audio/AudioNavigator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# AudioNavigator

`AudioNavigator` follows the [Readium Architecture](https://readium.org/architecture/) and implements `MediaNavigator` and `Configurable` interfaces.

## Instantiation and Destruction

`AudioNavigator` is ready to use immediately after instantiation. There is no separate `load()` method required - the navigator automatically initializes during construction.

### Instantiate

To use the `AudioNavigator`, you must first instantiate it by calling its constructor and passing in the required arguments. The constructor expects the following arguments:

- `publication`: The audio `Publication` object.
- `listeners`: An object that contains event listeners for the audio publication.
- `initialPosition`: A `Locator` object that represents the initial position in the publication (optional).
- `configuration`: An object that contains configuration options for the audio publication. This is relying on the Preferences API (optional). It also supports `contentProtection` and `keyboardPeripherals` options.

```js
const navigator = new AudioNavigator(
publication,
listeners,
initialPosition,
configuration
);
```

To create an instance of `AudioNavigator`, you only need a `Publication` and listeners. All other arguments are optional.

To create a `Publication` object, please refer to the [Handling Publications](../HandlingPublications.md) document.

To customize listeners, please refer to the [Customizing Audio Listeners](./CustomizingListeners.md) document.

The `initialPosition` is the position at which the `AudioNavigator` will start playback. It has to be a `Locator` with time-based locations.

Finally, `AudioNavigator` implements a `Configurable` interface, so that it can be configured dynamically through the `configuration` argument. Please refer to [Configuring the AudioNavigator](./ConfiguringAudioNavigator.md) for more information.

`AudioNavigator` also supports content protection and keyboard peripherals through the `configuration` argument:

- `contentProtection`: Configures navigator-level protection features (automation detection, dev tools monitoring, print protection, etc.). See [Content Protection](./ContentProtection.md).
- `keyboardPeripherals`: Configures custom keyboard shortcuts that are intercepted at the navigator level. See [Keyboard Peripherals](./KeyboardPeripherals.md).

### Destroy

To destroy the `AudioNavigator` instance, you can call the `destroy` method. This method takes no arguments and cleans up all resources.

```js
navigator.destroy();
console.log('Instance destroyed');
```

### Properties

Additionally, the `AudioNavigator` class provides the following properties:

- `publication`: The publication (`Publication`) rendered by this navigator.
- `currentLocator`: The current position (`Locator`) in the publication. Can be used to save a bookmark to the current position.
- `timeline`: The `Timeline` for the publication. See [Timeline](#timeline).
- `isPlaying`: Returns `true` if audio is currently playing.
- `isPaused`: Returns `true` if audio is currently paused.
- `duration`: Returns the duration of the current audio track in seconds.
- `currentTime`: Returns the current playback time in seconds.
- `remotePlayback`: The [`RemotePlayback`](https://developer.mozilla.org/en-US/docs/Web/API/RemotePlayback) object for the primary media element. Use it to prompt the device picker, watch device availability, and read the current connection state. See [Remote Playback](./RemotePlayback.md).

### Preferences API

The `AudioNavigator` class provides a Preferences API that allows you to configure audio playback. The Preferences API includes the following:

- `submitPreferences(preferences)`: Submit a set of preferences to the publication.
- `settings`: Get the current settings for the publication.
- `preferencesEditor`: Get the preferences editor for the publication.

See [Configuring the AudioNavigator](./ConfiguringAudioNavigator.md) for more information.

## Navigation

The `AudioNavigator` class exposes several methods for navigating the audio publication. These methods are defined in the `MediaNavigator` abstract class and include:

- `go(locator: Locator, animated: boolean, cb: callback)`: Moves to the position in the publication corresponding to the given Locator.
- `goLink(link: Link, animated: boolean, cb: callback)`: Moves to the position in the publication targeted by the given Link.
- `goForward(animated: boolean, cb: callback)`: Moves to the next track in the reading progression.
- `goBackward(animated: boolean, cb: callback)`: Moves to the previous track in the reading progression.

```js
const locator = new Locator({
href: 'audio/track-1.mp3',
locations: new LocatorLocations({
progression: 0.5,
fragments: ['t=30']
})
});
navigator.go(locator, false, (success) => {
if (success) {
console.log('Navigated to Track 1 at 30 seconds');
}
});

const link = new Link({ href: 'audio/track-2.mp3' });
navigator.goLink(link, false, (success) => {
if (success) {
console.log('Navigated to Track 2');
}
});

navigator.goForward(false, (success) => {
if (success) {
console.log('Navigated to next track');
}
});

navigator.goBackward(false, (success) => {
if (success) {
console.log('Navigated to previous track');
}
});
```

## Playback Control

The `AudioNavigator` class provides methods for controlling audio playback:

- `play()`: Starts or resumes audio playback.
- `pause()`: Pauses audio playback.
- `stop()`: Stops audio playback and resets to the beginning.
- `seek(time: number)`: Seeks to a specific time in seconds.
- `jump(seconds: number)`: Jumps forward or backward by the specified number of seconds.
- `skipForward()`: Skips forward by the configured interval.
- `skipBackward()`: Skips backward by the configured interval.

```js
// Basic playback control
navigator.play();
navigator.pause();
navigator.stop();

// Navigation within tracks
navigator.seek(30); // Seek to 30 seconds
navigator.jump(10); // Jump forward 10 seconds
navigator.jump(-5); // Jump backward 5 seconds

// Skip by configured intervals
navigator.skipForward(); // Skip forward by skipForwardInterval
navigator.skipBackward(); // Skip backward by skipBackwardInterval
```

## Timeline

The `AudioNavigator` exposes a `timeline` property that contextualizes the publication's reading order and table of contents. See [Timeline](./Timeline.md) for full documentation.

## Remote Playback

The `AudioNavigator` exposes a `remotePlayback` property that gives access to the browser's [Remote Playback API](https://developer.mozilla.org/en-US/docs/Web/API/Remote_Playback_API), enabling users to cast audio to AirPlay or Chromecast devices. See [Remote Playback](./RemotePlayback.md) for full documentation.

## Helpers

Finally, `AudioNavigator` provides helpers to help derive information about navigation and playback state:

- `canGoForward`: Returns `true` if the navigator can go to the next track.
- `canGoBackward`: Returns `true` if the navigator can go to the previous track.
- `isTrackStart`: Returns `true` if at the beginning of the current track.
- `isTrackEnd`: Returns `true` if at the end of the current track.

These can come in handy if you want to disable navigation buttons when the user is at the start or end of a track, or show different UI controls based on the current playback state.

```js
// Update UI based on navigation state
const nextButton = document.getElementById('next-button');
nextButton.disabled = !navigator.canGoForward;

const prevButton = document.getElementById('prev-button');
prevButton.disabled = !navigator.canGoBackward;

// Update UI based on track position
if (navigator.isTrackStart) {
console.log('At the beginning of the track');
}

if (navigator.isTrackEnd) {
console.log('At the end of the track');
}
```
Loading
Loading