@readium/shared 2.2.1 → 2.2.3
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/dist/index.js +511 -490
- package/dist/index.umd.cjs +3 -3
- package/package.json +1 -1
- package/src/opds/Acquisition.ts +1 -1
- package/src/opds/Availability.ts +1 -1
- package/src/opds/Copies.ts +1 -1
- package/src/opds/Holds.ts +1 -1
- package/src/opds/Price.ts +1 -1
- package/src/publication/Publication.ts +0 -2
- package/src/publication/html/Locations.ts +4 -4
- package/src/publication/opds/Properties.ts +2 -2
- package/src/publication/services/timeline/Timeline.ts +9 -9
- package/src/util/index.ts +1 -0
- package/src/util/npt.ts +51 -0
- package/types/src/opds/Acquisition.d.ts +1 -1
- package/types/src/opds/Availability.d.ts +1 -1
- package/types/src/opds/Copies.d.ts +1 -1
- package/types/src/opds/Holds.d.ts +1 -1
- package/types/src/opds/Price.d.ts +1 -1
- package/types/src/publication/Publication.d.ts +0 -1
- package/types/src/publication/opds/Properties.d.ts +1 -1
- package/types/src/publication/services/timeline/Timeline.d.ts +2 -3
- package/types/src/util/index.d.ts +1 -0
- package/types/src/util/npt.d.ts +20 -0
package/package.json
CHANGED
package/src/opds/Acquisition.ts
CHANGED
package/src/opds/Availability.ts
CHANGED
package/src/opds/Copies.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { positiveNumberfromJSON } from '../util/JSONParse.ts';
|
|
|
8
8
|
/**
|
|
9
9
|
* Library-specific feature that contains information about the copies that a library has acquired.
|
|
10
10
|
*
|
|
11
|
-
* https://
|
|
11
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
12
12
|
*/
|
|
13
13
|
export class Copies {
|
|
14
14
|
public total?: number;
|
package/src/opds/Holds.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { positiveNumberfromJSON } from '../util/JSONParse.ts';
|
|
|
8
8
|
/**
|
|
9
9
|
* Library-specific features when a specific book is unavailable but provides a hold list.
|
|
10
10
|
*
|
|
11
|
-
* https://
|
|
11
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
12
12
|
*/
|
|
13
13
|
export class Holds {
|
|
14
14
|
public total?: number;
|
package/src/opds/Price.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { positiveNumberfromJSON } from '../util/JSONParse.ts';
|
|
|
8
8
|
/**
|
|
9
9
|
* The price of a publication in an OPDS link.
|
|
10
10
|
*
|
|
11
|
-
* https://
|
|
11
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
12
12
|
*
|
|
13
13
|
* currency Currency for the price, eg. EUR.
|
|
14
14
|
* value Price value, should only be used for display purposes, because of precision issues
|
|
@@ -14,8 +14,6 @@ import { GuidedNavigationDocument } from "./GuidedNavigation.ts";
|
|
|
14
14
|
import { MediaType, URITemplate } from "../util/index.ts";
|
|
15
15
|
import { Timeline } from './services/timeline/Timeline.ts';
|
|
16
16
|
|
|
17
|
-
export type ServiceFactory = () => null;
|
|
18
|
-
|
|
19
17
|
/** Shared model for a Readium Publication. */
|
|
20
18
|
export class Publication {
|
|
21
19
|
/** The manifest holding the publication metadata extracted from the publication file */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LocatorLocations } from '../Locator.ts';
|
|
2
2
|
import { DomRange } from './DomRange.ts';
|
|
3
|
+
import { parseNptTime } from '../../util/npt.ts';
|
|
3
4
|
|
|
4
5
|
// HTML extensions for [Locations].
|
|
5
6
|
// https://github.com/readium/architecture/blob/master/models/locators/extensions/html.md
|
|
@@ -112,10 +113,9 @@ LocatorLocations.prototype.page = function(): number | undefined {
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
LocatorLocations.prototype.time = function(): number | undefined {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return undefined;
|
|
116
|
+
const raw = this.fragmentParameters().get("t");
|
|
117
|
+
if (!raw) return undefined;
|
|
118
|
+
return parseNptTime(raw);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
LocatorLocations.prototype.space = function(): [number, number, number, number] | undefined {
|
|
@@ -4,7 +4,7 @@ import { Link } from '../Link.ts';
|
|
|
4
4
|
import { Properties } from '../Properties.ts';
|
|
5
5
|
|
|
6
6
|
// OPDS extensions for link [Properties].
|
|
7
|
-
// https://
|
|
7
|
+
// https://specs.opds.io/schema/properties.schema.json
|
|
8
8
|
|
|
9
9
|
declare module '../Properties' {
|
|
10
10
|
export interface Properties {
|
|
@@ -43,7 +43,7 @@ declare module '../Properties' {
|
|
|
43
43
|
* Indicates that the linked resource supports authentication with the associated Authentication
|
|
44
44
|
* Document.
|
|
45
45
|
*
|
|
46
|
-
* See https://
|
|
46
|
+
* See https://specs.opds.io/authentication-for-opds-1.0.html
|
|
47
47
|
*/
|
|
48
48
|
getAuthenticate(): Link | undefined;
|
|
49
49
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Link, Links } from "../../Link.ts";
|
|
2
2
|
import { Locator } from "../../Locator.ts";
|
|
3
3
|
import { TimelineItem } from "./TimelineItem.ts";
|
|
4
|
+
import { isNptStartOfResource, parseNptTime } from "../../../util/npt.ts";
|
|
4
5
|
|
|
5
6
|
interface PublicationLike {
|
|
6
7
|
toc?: Links;
|
|
@@ -271,15 +272,14 @@ export class Timeline {
|
|
|
271
272
|
|
|
272
273
|
/**
|
|
273
274
|
* A TOC href points to the start of its resource when it has no fragment,
|
|
274
|
-
* or when the fragment contains a parsable `t=` value of 0 (audio:
|
|
275
|
-
* beginning of the file).
|
|
276
|
-
* or `foo=bar&t=0`.
|
|
275
|
+
* or when the fragment contains a parsable NPT `t=` value of 0 (audio:
|
|
276
|
+
* explicit beginning of the file).
|
|
277
277
|
*/
|
|
278
278
|
private static isStartOfResource(href: string): boolean {
|
|
279
279
|
const fragment = href.split("#")[1];
|
|
280
280
|
if (!fragment) return true;
|
|
281
|
-
const match = fragment.match(/(?:^|&)t=(
|
|
282
|
-
return match !== null &&
|
|
281
|
+
const match = fragment.match(/(?:^|&)t=([^&]+)/);
|
|
282
|
+
return match !== null && isNptStartOfResource(match[1]);
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
// -------------------------------------------------------------------------
|
|
@@ -322,8 +322,8 @@ export class Timeline {
|
|
|
322
322
|
const effectiveHref = refHref || this.bareHrefFromItem(item);
|
|
323
323
|
if (effectiveHref !== href) continue;
|
|
324
324
|
if (!refFragment) return undefined;
|
|
325
|
-
const match = refFragment.match(/(?:^|&)t=(
|
|
326
|
-
return match ?
|
|
325
|
+
const match = refFragment.match(/(?:^|&)t=([^&]+)/);
|
|
326
|
+
return match ? parseNptTime(match[1]) : undefined;
|
|
327
327
|
}
|
|
328
328
|
return undefined;
|
|
329
329
|
}
|
|
@@ -337,8 +337,8 @@ export class Timeline {
|
|
|
337
337
|
if (!ref) return undefined;
|
|
338
338
|
const fragment = ref.split("#")[1];
|
|
339
339
|
if (!fragment) return undefined;
|
|
340
|
-
const match = fragment.match(/(?:^|&)t=(
|
|
341
|
-
return match ?
|
|
340
|
+
const match = fragment.match(/(?:^|&)t=([^&]+)/);
|
|
341
|
+
return match ? parseNptTime(match[1]) : undefined;
|
|
342
342
|
}
|
|
343
343
|
|
|
344
344
|
private ancestorPath(items: TimelineItem[], target: TimelineItem): TimelineItem[] | null {
|
package/src/util/index.ts
CHANGED
package/src/util/npt.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a W3C Media Fragments NPT (Normal Play Time) temporal value and
|
|
3
|
+
* returns the corresponding time in seconds.
|
|
4
|
+
*
|
|
5
|
+
* Accepts the start of a range expression (e.g. "10,20" → 10).
|
|
6
|
+
* Handles the optional "npt:" prefix and all three clock formats:
|
|
7
|
+
* - Seconds: "1647.202" or "npt:1647.202"
|
|
8
|
+
* - MM:SS: "27:27.2" or "npt:27:27.2"
|
|
9
|
+
* - HH:MM:SS: "0:27:27.2" or "npt:0:27:27.202"
|
|
10
|
+
*
|
|
11
|
+
* Returns `undefined` for any value that cannot be parsed.
|
|
12
|
+
*
|
|
13
|
+
* https://www.w3.org/TR/media-frags/#naming-time
|
|
14
|
+
*/
|
|
15
|
+
export function parseNptTime(raw: string): number | undefined {
|
|
16
|
+
const start = raw.split(",")[0].trim();
|
|
17
|
+
const normalizedStart = start.toLowerCase();
|
|
18
|
+
const s = normalizedStart.startsWith("npt:") ? start.slice(4) : start;
|
|
19
|
+
const parts = s.split(":");
|
|
20
|
+
|
|
21
|
+
if (parts.length === 1) {
|
|
22
|
+
const sec = parseFloat(parts[0]);
|
|
23
|
+
return isNaN(sec) ? undefined : sec;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (parts.length === 2) {
|
|
27
|
+
const min = parseInt(parts[0], 10);
|
|
28
|
+
const sec = parseFloat(parts[1]);
|
|
29
|
+
if (isNaN(min) || isNaN(sec)) return undefined;
|
|
30
|
+
return min * 60 + sec;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (parts.length === 3) {
|
|
34
|
+
const hr = parseInt(parts[0], 10);
|
|
35
|
+
const min = parseInt(parts[1], 10);
|
|
36
|
+
const sec = parseFloat(parts[2]);
|
|
37
|
+
if (isNaN(hr) || isNaN(min) || isNaN(sec)) return undefined;
|
|
38
|
+
return hr * 3600 + min * 60 + sec;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns true when the NPT time value represents the start of a resource
|
|
46
|
+
* (t=0, t=0.0, t=npt:0, t=npt:0:0:0, etc.).
|
|
47
|
+
*/
|
|
48
|
+
export function isNptStartOfResource(raw: string): boolean {
|
|
49
|
+
const t = parseNptTime(raw);
|
|
50
|
+
return t !== undefined && t === 0;
|
|
51
|
+
}
|
|
@@ -6,7 +6,7 @@ export declare enum AvailabilityStatus {
|
|
|
6
6
|
/**
|
|
7
7
|
* Indicated the availability of a given resource.
|
|
8
8
|
*
|
|
9
|
-
* https://
|
|
9
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
export declare class Availability {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Library-specific feature that contains information about the copies that a library has acquired.
|
|
3
3
|
*
|
|
4
|
-
* https://
|
|
4
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
5
5
|
*/
|
|
6
6
|
export declare class Copies {
|
|
7
7
|
total?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Library-specific features when a specific book is unavailable but provides a hold list.
|
|
3
3
|
*
|
|
4
|
-
* https://
|
|
4
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
5
5
|
*/
|
|
6
6
|
export declare class Holds {
|
|
7
7
|
total?: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The price of a publication in an OPDS link.
|
|
3
3
|
*
|
|
4
|
-
* https://
|
|
4
|
+
* https://specs.opds.io/schema/properties.schema.json
|
|
5
5
|
*
|
|
6
6
|
* currency Currency for the price, eg. EUR.
|
|
7
7
|
* value Price value, should only be used for display purposes, because of precision issues
|
|
@@ -7,7 +7,6 @@ import { PublicationCollection } from './PublicationCollection.ts';
|
|
|
7
7
|
import { Resource } from '../fetcher/Resource.ts';
|
|
8
8
|
import { GuidedNavigationDocument } from "./GuidedNavigation.ts";
|
|
9
9
|
import { Timeline } from './services/timeline/Timeline.ts';
|
|
10
|
-
export type ServiceFactory = () => null;
|
|
11
10
|
/** Shared model for a Readium Publication. */
|
|
12
11
|
export declare class Publication {
|
|
13
12
|
/** The manifest holding the publication metadata extracted from the publication file */
|
|
@@ -31,7 +31,7 @@ declare module '../Properties' {
|
|
|
31
31
|
* Indicates that the linked resource supports authentication with the associated Authentication
|
|
32
32
|
* Document.
|
|
33
33
|
*
|
|
34
|
-
* See https://
|
|
34
|
+
* See https://specs.opds.io/authentication-for-opds-1.0.html
|
|
35
35
|
*/
|
|
36
36
|
getAuthenticate(): Link | undefined;
|
|
37
37
|
}
|
|
@@ -76,9 +76,8 @@ export declare class Timeline {
|
|
|
76
76
|
private static collectTocCandidates;
|
|
77
77
|
/**
|
|
78
78
|
* A TOC href points to the start of its resource when it has no fragment,
|
|
79
|
-
* or when the fragment contains a parsable `t=` value of 0 (audio:
|
|
80
|
-
* beginning of the file).
|
|
81
|
-
* or `foo=bar&t=0`.
|
|
79
|
+
* or when the fragment contains a parsable NPT `t=` value of 0 (audio:
|
|
80
|
+
* explicit beginning of the file).
|
|
82
81
|
*/
|
|
83
82
|
private static isStartOfResource;
|
|
84
83
|
private static trimToDepth;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a W3C Media Fragments NPT (Normal Play Time) temporal value and
|
|
3
|
+
* returns the corresponding time in seconds.
|
|
4
|
+
*
|
|
5
|
+
* Accepts the start of a range expression (e.g. "10,20" → 10).
|
|
6
|
+
* Handles the optional "npt:" prefix and all three clock formats:
|
|
7
|
+
* - Seconds: "1647.202" or "npt:1647.202"
|
|
8
|
+
* - MM:SS: "27:27.2" or "npt:27:27.2"
|
|
9
|
+
* - HH:MM:SS: "0:27:27.2" or "npt:0:27:27.202"
|
|
10
|
+
*
|
|
11
|
+
* Returns `undefined` for any value that cannot be parsed.
|
|
12
|
+
*
|
|
13
|
+
* https://www.w3.org/TR/media-frags/#naming-time
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseNptTime(raw: string): number | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Returns true when the NPT time value represents the start of a resource
|
|
18
|
+
* (t=0, t=0.0, t=npt:0, t=npt:0:0:0, etc.).
|
|
19
|
+
*/
|
|
20
|
+
export declare function isNptStartOfResource(raw: string): boolean;
|