@readium/shared 2.3.2 → 2.4.0
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getTime as g,getHtmlId as v}from"../../html/Locations.js";import{Profile as p}from"../../Profiles.js";import{isNptStartOfResource as k,formatNptTime as I,parseNptTime as T}from"../../../util/npt.js";class l{constructor(i,t,e=[],s=[],n=void 0){this._trimmedLinkMap=new Map,this._allItems=i,this.linkMap=t,this._conformsTo=e,this.tocLinks=s,this._tocDepth=n}static build(i,t={}){const e=i.toc?.items??[],s=i.readingOrder.items,{depth:n}=t,o=i.metadata?.conformsTo??[],r=new Map,c=[];for(let h=0;h<s.length;h++){const f=s[h],a=l.bareHref(f.href),d=f.title??l.findTitleInToc(e,a,n),u=l.collectChildrenFromToc(e,a,n,1,r),m={title:d,references:[f.href],children:u.length>0?u:void 0};r.set(m,f),c.push(m)}return new l(c,r,o,e,n)}augment(i){for(const t of this.flatAll){const e=this.linkFor(t);if(!e)continue;const s=i(t,e);s.position!==void 0&&(t.position=s.position),s.scroll!==void 0&&(t.scroll=s.scroll),s.role!==void 0&&(t.role=s.role)}}get depth(){return this._depth}set depth(i){this._depth!==i&&(this._depth=i,this._tocDepth=i,this._items=void 0,this._flat=void 0,this._toc=void 0)}get items(){return this._items||(this._depth!==void 0?(this._trimmedLinkMap=new Map,this._items=l.trimToDepth(this._allItems,this._depth,this.linkMap,this._trimmedLinkMap)):this._items=this._allItems),this._items}locate(i){const t=i.href.split("#")[0],e=g(i.locations),s=v(i.locations),n=i.locations.progression;if(e!==void 0){let o=-1/0,r;for(const c of this.flat){if(!this.itemMatchesHref(c,t))continue;const h=this.itemStartTime(c,t);h!==void 0&&h<=e&&h>o&&(o=h,r=c)}if(r)return r}if(s){const o=this.flat.find(r=>this.itemMatchesHref(r,t)?r.references.some(c=>c.split("#")[1]===s):!1);if(o)return o}if(n!==void 0){let o=-1/0,r;for(const h of this.flat){if(!this.itemMatchesHref(h,t))continue;const f=this.itemScrollPosition(h);f!==void 0&&f<=n&&f>o&&(o=f,r=h)}if(r)return r;const c=this.items.find(h=>this.itemMatchesHref(h,t));if(c?.children?.length&&!c.children.some(h=>h.scroll!==void 0)){const h=Math.min(Math.floor(n*c.children.length),c.children.length-1);return c.children[h]}}return this.flat.find(o=>this.itemMatchesHref(o,t))}
|
|
1
|
+
import{getTime as g,getHtmlId as v}from"../../html/Locations.js";import{Profile as p}from"../../Profiles.js";import{isNptStartOfResource as k,formatNptTime as I,parseNptTime as T}from"../../../util/npt.js";class l{constructor(i,t,e=[],s=[],n=void 0){this._trimmedLinkMap=new Map,this._allItems=i,this.linkMap=t,this._conformsTo=e,this.tocLinks=s,this._tocDepth=n}static build(i,t={}){const e=i.toc?.items??[],s=i.readingOrder.items,{depth:n}=t,o=i.metadata?.conformsTo??[],r=new Map,c=[];for(let h=0;h<s.length;h++){const f=s[h],a=l.bareHref(f.href),d=f.title??l.findTitleInToc(e,a,n),u=l.collectChildrenFromToc(e,a,n,1,r),m={title:d,references:[f.href],children:u.length>0?u:void 0};r.set(m,f),c.push(m)}return new l(c,r,o,e,n)}augment(i){for(const t of this.flatAll){const e=this.linkFor(t);if(!e)continue;const s=i(t,e);s.position!==void 0&&(t.position=s.position),s.scroll!==void 0&&(t.scroll=s.scroll),s.role!==void 0&&(t.role=s.role)}}get depth(){return this._depth}set depth(i){this._depth!==i&&(this._depth=i,this._tocDepth=i,this._items=void 0,this._flat=void 0,this._toc=void 0)}get items(){return this._items||(this._depth!==void 0?(this._trimmedLinkMap=new Map,this._items=l.trimToDepth(this._allItems,this._depth,this.linkMap,this._trimmedLinkMap)):this._items=this._allItems),this._items}locate(i){const t=i.href.split("#")[0],e=g(i.locations),s=v(i.locations),n=i.locations.progression;if(e!==void 0){let o=-1/0,r;for(const c of this.flat){if(!this.itemMatchesHref(c,t))continue;const h=this.itemStartTime(c,t);h!==void 0&&h<=e&&h>o&&(o=h,r=c)}if(r)return r}if(s){const o=this.flat.find(r=>this.itemMatchesHref(r,t)?r.references.some(c=>c.split("#")[1]===s):!1);if(o)return o}if(n!==void 0){let o=-1/0,r;for(const h of this.flat){if(!this.itemMatchesHref(h,t))continue;const f=this.itemScrollPosition(h);f!==void 0&&f<=n&&f>o&&(o=f,r=h)}if(r)return r;const c=this.items.find(h=>this.itemMatchesHref(h,t));if(c?.children?.length&&!c.children.some(h=>h.scroll!==void 0)){const h=Math.min(Math.floor(n*c.children.length),c.children.length-1);return c.children[h]}}return this.flat.find(o=>this.itemMatchesHref(o,t))}navigableFrom(i){const t=this.flat.indexOf(i);return{previous:t>0?this.flat[t-1]:void 0,next:t>=0&&t<this.flat.length-1?this.flat[t+1]:void 0}}segmentsForHref(i){const t=i.split("#")[0],e=this.items.find(s=>this.itemMatchesHref(s,t));return e?e.children?.length?e.children:[e]:[]}ancestors(i){return this.ancestorPath(this.items,i)??[]}linkFor(i){return this.linkMap.get(i)??this._trimmedLinkMap.get(i)}get contextualizedToc(){return this._toc||(this._toc=this.tocLinks.length>0?this.buildTocEntries(this.tocLinks,this._tocDepth,1):this._allItems.map(i=>this.entryFor(this.linkFor(i),i))),this._toc}tocEntryFor(i){const t=this.linkFor(i);if(!t)return;const e=this.findTocEntryByLink(this.contextualizedToc,t);if(e)return e;const s=this.nearestTocEntryForResource(t.href,i);return s||this.previousResolvedTocEntry(t)}get flat(){return this._flat||(this._flat=this.flattenItems(this.items)),this._flat}get flatAll(){return this.flattenItems(this._allItems)}static findTitleInToc(i,t,e){const{atStart:s,fragments:n}=l.collectTocCandidates(i,t,e,1);if(s.length>0)return s[0].title;if(n.length===1)return n[0].title}static collectChildrenFromToc(i,t,e,s,n){if(e!==void 0&&s>e)return[];const o=[];for(const r of i){const c=l.bareHref(r.href),h=r.href.startsWith("#");if((c===t||h&&c==="")&&r.title&&!l.isStartOfResource(r.href)){const a=c===""?t+r.href:r.href,d={title:r.title,references:[a]};n.set(d,r),o.push(d)}r.children?.items?.length&&o.push(...l.collectChildrenFromToc(r.children.items,t,e,s+1,n))}return o}static collectTocCandidates(i,t,e,s){if(e!==void 0&&s>e)return{atStart:[],fragments:[]};const n=[],o=[];for(const r of i){const c=l.bareHref(r.href),h=r.href.startsWith("#");if((c===t||h&&c==="")&&r.title&&(l.isStartOfResource(r.href)?n.push(r):o.push(r)),r.children?.items?.length){const f=l.collectTocCandidates(r.children.items,t,e,s+1);n.push(...f.atStart),o.push(...f.fragments)}}return{atStart:n,fragments:o}}static isStartOfResource(i){const t=i.split("#")[1];if(!t)return!0;const e=t.match(/(?:^|&)t=([^&]+)/);return e!==null&&k(e[1])}get linkToItem(){if(!this._linkToItem){this._linkToItem=new Map;for(const[i,t]of this.linkMap)this._linkToItem.set(t,i)}return this._linkToItem}buildTocEntries(i,t,e){return t!==void 0&&e>t?[]:i.map(s=>{const n=this.linkToItem.get(s)??this.resourceStartItem(s.href),o=s.children?.items?.length?this.buildTocEntries(s.children.items,t,e+1):[];return{...this.entryFor(s,n),children:o.length>0?o:void 0}})}tocLinksFlat(i,t,e){if(t!==void 0&&e>t)return[];const s=[];for(const n of i)s.push(n),n.children?.items?.length&&s.push(...this.tocLinksFlat(n.children.items,t,e+1));return s}entryFor(i,t){const e=this._conformsTo.includes(p.AUDIOBOOK);return{link:i,position:!e&&t?.position!==void 0?String(t.position):void 0,timestamp:e&&t?.position!==void 0?I(t.position):void 0}}resourceStartItem(i){const t=l.bareHref(i);return this._allItems.find(e=>this.itemMatchesHref(e,t))}findTocEntryByLink(i,t){for(const e of i){if(e.link===t)return e;if(e.children){const s=this.findTocEntryByLink(e.children,t);if(s)return s}}}nearestTocEntryForResource(i,t){const e=l.bareHref(i),s=this.tocLinksFlat(this.tocLinks,this._tocDepth,1).filter(f=>l.bareHref(f.href)===e).map(f=>({link:f,item:this.linkToItem.get(f)??this.resourceStartItem(f.href)}));if(s.length===0)return;const n=this._conformsTo.includes(p.AUDIOBOOK),o=n?t.position??0:t.scroll??0;let r,c=-1/0;for(const f of s){const a=n?f.item?.position??0:f.item?.scroll??0;a<=o&&a>c&&(c=a,r=f)}const h=r??s[0];return this.findTocEntryByLink(this.contextualizedToc,h.link)}previousResolvedTocEntry(i){const t=this._allItems.findIndex(e=>this.linkFor(e)===i);if(t!==-1)for(let e=t-1;e>=0;e--){const s=this.linkFor(this._allItems[e]);if(!s)continue;const n=l.bareHref(s.href),{atStart:o,fragments:r}=l.collectTocCandidates(this.tocLinks,n,this._tocDepth,1),c=o.filter(d=>l.bareHref(d.href)===n),h=r.filter(d=>l.bareHref(d.href)===n),f=c[0]??(h.length>0?h[h.length-1]:void 0);if(!f)continue;const a=this.findTocEntryByLink(this.contextualizedToc,f);if(a)return a}}static trimToDepth(i,t,e,s){return i.map(n=>{const o={...n,children:t>1&&n.children?.length?l.trimToDepth(n.children,t-1,e,s):void 0},r=e.get(n);return r&&s.set(o,r),o})}flattenItems(i){const t=[];for(const e of i)t.push(e),e.children&&t.push(...this.flattenItems(e.children));return t}itemStartTime(i,t){for(const e of i.references){const s=e.indexOf("#"),n=s>=0?e.slice(0,s):e,o=s>=0?e.slice(s+1):void 0;if((n||t)!==t)continue;if(!o)return;const c=o.match(/(?:^|&)t=([^&]+)/);return c?T(c[1]):void 0}}itemMatchesHref(i,t){return i.references.some(e=>{const s=e.split("#")[0];return s===t||s===""})}ancestorPath(i,t){for(const e of i){if(e===t)return[];if(e.children){const s=this.ancestorPath(e.children,t);if(s!==null)return[e,...s]}}return null}itemScrollPosition(i){return i.scroll}static bareHref(i){return i.split("#")[0]}}export{l as Timeline};
|
package/package.json
CHANGED
|
@@ -228,7 +228,8 @@ export class Timeline {
|
|
|
228
228
|
return this.flat.find(item => this.itemMatchesHref(item, href));
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
/** The items navigable to/from `item`: its previous/next neighbors in the flattened timeline. */
|
|
232
|
+
navigableFrom(item: TimelineItem): { previous: TimelineItem | undefined; next: TimelineItem | undefined } {
|
|
232
233
|
const index = this.flat.indexOf(item);
|
|
233
234
|
return {
|
|
234
235
|
previous: index > 0 ? this.flat[index - 1] : undefined,
|
|
@@ -88,7 +88,8 @@ export declare class Timeline {
|
|
|
88
88
|
/** Top-level timeline items. Cached; invalidated when `depth` changes. */
|
|
89
89
|
get items(): TimelineItem[];
|
|
90
90
|
locate(locator: Locator): TimelineItem | undefined;
|
|
91
|
-
|
|
91
|
+
/** The items navigable to/from `item`: its previous/next neighbors in the flattened timeline. */
|
|
92
|
+
navigableFrom(item: TimelineItem): {
|
|
92
93
|
previous: TimelineItem | undefined;
|
|
93
94
|
next: TimelineItem | undefined;
|
|
94
95
|
};
|