@aceshooting/lyra-ui 8.0.0 → 8.1.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.
- package/CHANGELOG.md +188 -17
- package/custom-elements.json +1 -1
- package/dist/components/agent-tools/mcp-app/mcp-app.class.js +1 -1
- package/dist/components/agent-tools/terminal/terminal.class.js +2 -2
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.d.ts +5 -0
- package/dist/components/conversation/selection-toolbar/selection-toolbar.class.js +1 -1
- package/dist/components/conversation/widget-renderer/widget-renderer.class.js +1 -1
- package/dist/components/data/data-grid/data-grid.class.js +1 -1
- package/dist/components/data/flow-minimap/flow-minimap.class.js +1 -1
- package/dist/components/data/query-builder/query-builder.class.js +2 -2
- package/dist/components/data/table/table.class.js +2 -2
- package/dist/components/data/table/table.styles.js +8 -3
- package/dist/components/data/tree/tree-item.styles.js +11 -3
- package/dist/components/data/tree/tree.class.d.ts +11 -0
- package/dist/components/data/tree/tree.class.js +1 -1
- package/dist/components/forms/icon-button/icon-button.class.js +1 -1
- package/dist/components/forms/locale-picker/locale-picker.class.d.ts +3 -0
- package/dist/components/forms/locale-picker/locale-picker.class.js +4 -3
- package/dist/components/forms/locale-picker/locale-picker.styles.js +4 -0
- package/dist/components/forms/switch/switch.styles.js +9 -0
- package/dist/components/media/attachment-chip/attachment-chip.class.js +2 -2
- package/dist/components/media/avatar/avatar.class.js +2 -2
- package/dist/components/media/flag/flag.class.js +2 -2
- package/dist/components/retrieval/entity-card/entity-card.class.js +1 -1
- package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +1 -1
- package/dist/components/utility/icon/icon.class.js +1 -1
- package/dist/components/viewers/archive-viewer/archive-viewer.class.js +1 -1
- package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +1 -1
- package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +3 -2
- package/dist/components/viewers/page-rail/page-rail.class.js +2 -0
- package/dist/components/viewers/spreadsheet-viewer/spreadsheet-viewer.class.js +1 -1
- package/dist/internal/anchor-target.js +1 -1
- package/dist/internal/package-metadata.d.ts +1 -1
- package/dist/internal/package-metadata.js +1 -1
- package/dist/internal/safe-svg.d.ts +13 -0
- package/dist/internal/safe-svg.js +1 -0
- package/dist/testing/happy-dom-shims.d.ts +4 -0
- package/dist/testing/happy-dom-shims.js +1 -1
- package/llms/components/lr-attachment-chip.md +18 -10
- package/llms/components/lr-locale-picker.md +6 -4
- package/llms/peers.md +3 -3
- package/llms-full.txt +23 -13
- package/package.json +8 -7
- package/vscode-html-data.json +7 -7
- package/web-types.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing,svg}from"lit";import{property,query,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAccessibilityVisible,srOnly}from"../../../internal/a11y.js";import{finiteNumber}from"../../../internal/numbers.js";import{safeFetchUrl}from"../../../internal/safe-url.js";import{isAbortError,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getIconLibrary,subscribeIconLibrary}from"./icon-library.js";import{acquireSanitizedIconResource,IconResourceError}from"./icon-resource.js";import{styles}from"./icon.styles.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_iconLoadError,LYRA_DEFAULT_iconSanitizerMissing,LYRA_DEFAULT_iconTooLarge,LYRA_DEFAULT_loading,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const PATHS={add:"M12 5v14M5 12h14",check:"m5 12 4 4L19 6",close:"m6 6 12 12M18 6 6 18",search:"m21 21-4.35-4.35M10.5 18a7.5 7.5 0 1 1 0-15 7.5 7.5 0 0 1 0 15Z",menu:"M4 6h16M4 12h16M4 18h16","chevron-left":"m15 18-6-6 6-6","chevron-right":"m9 18 6-6-6-6","chevron-down":"m6 9 6 6 6-6",calendar:"M6 3v3M18 3v3M4 9h16M5 5h14a1 1 0 0 1 1 1v13H4V6a1 1 0 0 1 1-1Z",command:"M6 6h4v4H6zM14 6h4v4h-4zM6 14h4v4H6zM14 14h4v4h-4z",trash:"M4 7h16M10 11v6M14 11v6M6 7l1 14h10l1-14M9 7V4h6v3"};class LyraIcon extends LyraElement{constructor(){super(...arguments);this._name="";this.path="";this.label="";this.library="default";this.family="";this.variant="";this._src="";this.rotate=0;this.autoWidth=false;this.swapOpacity=false;this.fixedWidth=false;this.fetchState={kind:"idle"};this.generation=0;this.onCustomSlotChange=()=>{this.syncCustomNodes()}}static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,iconLoadError:LYRA_DEFAULT_iconLoadError,iconSanitizerMissing:LYRA_DEFAULT_iconSanitizerMissing,iconTooLarge:LYRA_DEFAULT_iconTooLarge,loading:LYRA_DEFAULT_loading,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,styles,srOnly]}get name(){return this._name}set name(value){const old=this._name;this._name=value??"";this.requestUpdate("name",old)}get src(){return this._src}set src(value){const old=this._src;this._src=value??"";this.requestUpdate("src",old)}connectedCallback(){super.connectedCallback();this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this});this.stopLibrarySubscription??=subscribeIconLibrary(name=>{if(name===this.library)void this.load()});if(this.hasUpdated){queueMicrotask(()=>{if(this.isConnected)this.syncCustomNodes()});if(this.hasRemoteSource())this.scheduleAfterUpdate(()=>void this.load())}}disconnectedCallback(){this.generation++;this.releaseResourceLease();this.stopLibrarySubscription?.();this.stopLibrarySubscription=void 0;this.customContentObserver?.disconnect();this.customContentObserver=void 0;this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;if(this.fetchState.kind!=="idle")this.fetchState={kind:"idle"};super.disconnectedCallback()}updated(changed){super.updated(changed);if(changed.has("rotate")){const angle=finiteNumber(this.rotate??0,0);if(angle)this.style.setProperty("--lr-icon-rotate",`${angle}deg`);else this.style.removeProperty("--lr-icon-rotate")}this.applyRemoteA11y();this.syncCustomNodes();if(changed.has("src")||changed.has("library")||changed.has("name")||changed.has("family")||changed.has("variant")){this.scheduleAfterUpdate(()=>void this.load())}}syncCustomNodes(){if(this.fetchState.kind!=="idle")return;const svgEl=this.svgEl;if(!svgEl)return;svgEl.querySelectorAll("[data-lr-custom-copy]").forEach(node=>node.remove());this.customContentObserver?.disconnect();const slot=this.customSlot;if(!slot)return;for(const node of slot.assignedNodes({flatten:true})){const copy=this.cloneSvgNode(node);if(!copy)continue;copy.setAttribute("data-lr-custom-copy","");svgEl.append(copy)}this.observeCustomContent(slot)}observeCustomContent(slot){this.customContentObserver?.disconnect();if(!this.isConnected)return;const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;this.customContentObserver??=new MutationObserverCtor(()=>{if(this.isConnected)this.syncCustomNodes()});for(const node of slot.assignedNodes({flatten:true})){if(node.nodeType===1){this.customContentObserver.observe(node,{attributes:true,childList:true,subtree:true})}}}cloneSvgNode(node){if(node.nodeType!==1)return null;const element=node;if(element.localName.includes("-"))return null;const copy=this.ownerDocument.createElementNS("http://www.w3.org/2000/svg",element.localName);for(const attribute of element.attributes){copy.setAttribute(attribute.name,attribute.value)}for(const child of element.childNodes){const childCopy=this.cloneSvgNode(child);if(childCopy)copy.append(childCopy);else if(child.nodeType===3){copy.append(this.ownerDocument.createTextNode(child.textContent??""))}}return copy}accessibleLabel(){return this.getAttribute("aria-label")??this.label}hasRemoteSource(){return Boolean(this.src||this.name&&this.library&&getIconLibrary(this.library))}releaseResourceLease(){this.resourceLease?.release();this.resourceLease=void 0}async load(){const generation=++this.generation;this.releaseResourceLease();const library=this.name&&this.library?getIconLibrary(this.library):void 0;if(!library&&!this.src){if(this.fetchState.kind!=="idle")this.fetchState={kind:"idle"};return}this.fetchState={kind:"loading"};let source=this.src;try{if(library){source=await library.resolver(this.name,this.family,this.variant);if(!this.isConnected||generation!==this.generation)return;if(typeof source!=="string")throw new TypeError("icon resolver did not return a URL")}}catch(error){await this.fail("load",generation,this.name,error);return}if(!source){if(this.isConnected&&generation===this.generation)this.fetchState={kind:"idle"};return}const safeSource=safeFetchUrl(source);if(!safeSource){await this.fail("load",generation,source,new Error("icon URL is not allowed"));return}const fetchTarget=resolveOwnerFetchTarget(this,safeSource);if(!fetchTarget){await this.fail("load",generation,safeSource,new Error("icon URL is not available"));return}let lease;try{lease=acquireSanitizedIconResource(fetchTarget);this.resourceLease=lease;const canonical=await lease.promise;if(!this.isConnected||generation!==this.generation)return;if(!canonical){this.fetchState={kind:"empty"};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource});return}const node=this.ownerDocument.importNode(canonical,true);library?.mutator?.(node);this.fetchState={kind:"loaded",node};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource})}catch(error){if(isAbortError(error))return;const reason=error instanceof IconResourceError?error.reason:"load";await this.fail(reason,generation,safeSource,error)}finally{if(this.resourceLease===lease)this.resourceLease=void 0;lease?.release()}}async fail(reason,generation,src,error){if(!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",reason};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;if(isAccessibilityVisible(this)){this.errorAnnouncementSink?.announce(this.errorMessage(reason))}this.emit("lr-error",{src,error})}errorMessage(reason){if(reason==="sanitizer")return this.localize("iconSanitizerMissing");if(reason==="too-large")return this.localize("iconTooLarge");return this.localize("iconLoadError")}applyRemoteA11y(){const state2=this.fetchState;if(state2.kind!=="loaded")return;const label=this.accessibleLabel();state2.node.setAttribute("part","svg");state2.node.setAttribute("focusable","false");state2.node.setAttribute("aria-hidden",label?"false":"true");if(label)state2.node.setAttribute("aria-label",label);else state2.node.removeAttribute("aria-label");for(const use of state2.node.querySelectorAll("use")){const parts=new Set((use.getAttribute("part")??"").split(/\s+/).filter(Boolean));parts.add("use");use.setAttribute("part",[...parts].join(" "))}}renderBuiltIn(){const path=this.path||PATHS[this.name]||"";const accessibleLabel=this.accessibleLabel();return html`<svg part="svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden=${accessibleLabel?"false":"true"} aria-label=${accessibleLabel||nothing} focusable="false">${path?svg`<path d=${path}></path>`:nothing}</svg>${path?nothing:html`<slot @slotchange=${this.onCustomSlotChange}></slot>`}`}render(){const state2=this.fetchState;switch(state2.kind){case"loaded":return html`${state2.node}`;case"error":return html`<span part="error" class="sr-only" aria-hidden="true">${this.errorMessage(state2.reason)}</span>`;case"empty":return html`<span part="empty" aria-hidden="true"></span>`;case"loading":return html``;case"idle":default:return this.renderBuiltIn()}}}__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"name",null);__decorate([property()],LyraIcon.prototype,"path",void 0);__decorate([property()],LyraIcon.prototype,"label",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"library",void 0);__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"family",void 0);__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"variant",void 0);__decorate([property()],LyraIcon.prototype,"src",null);__decorate([property({type:Number,reflect:true,useDefault:true})],LyraIcon.prototype,"rotate",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"flip",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"canvas",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"auto-width"})],LyraIcon.prototype,"autoWidth",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"swap-opacity"})],LyraIcon.prototype,"swapOpacity",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"animation",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"fixed-width"})],LyraIcon.prototype,"fixedWidth",void 0);__decorate([state()],LyraIcon.prototype,"fetchState",void 0);__decorate([query("svg")],LyraIcon.prototype,"svgEl",void 0);__decorate([query("slot")],LyraIcon.prototype,"customSlot",void 0);export{LyraIcon};
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing,svg}from"lit";import{property,query,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAccessibilityVisible,srOnly}from"../../../internal/a11y.js";import{finiteNumber}from"../../../internal/numbers.js";import{safeFetchUrl}from"../../../internal/safe-url.js";import{isUnsafeSvgCloneAttribute}from"../../../internal/safe-svg.js";import{isAbortError,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getIconLibrary,subscribeIconLibrary}from"./icon-library.js";import{acquireSanitizedIconResource,IconResourceError}from"./icon-resource.js";import{styles}from"./icon.styles.js";import{LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_iconLoadError,LYRA_DEFAULT_iconSanitizerMissing,LYRA_DEFAULT_iconTooLarge,LYRA_DEFAULT_loading,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const PATHS={add:"M12 5v14M5 12h14",check:"m5 12 4 4L19 6",close:"m6 6 12 12M18 6 6 18",search:"m21 21-4.35-4.35M10.5 18a7.5 7.5 0 1 1 0-15 7.5 7.5 0 0 1 0 15Z",menu:"M4 6h16M4 12h16M4 18h16","chevron-left":"m15 18-6-6 6-6","chevron-right":"m9 18 6-6-6-6","chevron-down":"m6 9 6 6 6-6",calendar:"M6 3v3M18 3v3M4 9h16M5 5h14a1 1 0 0 1 1 1v13H4V6a1 1 0 0 1 1-1Z",command:"M6 6h4v4H6zM14 6h4v4h-4zM6 14h4v4H6zM14 14h4v4h-4z",trash:"M4 7h16M10 11v6M14 11v6M6 7l1 14h10l1-14M9 7V4h6v3"};class LyraIcon extends LyraElement{constructor(){super(...arguments);this._name="";this.path="";this.label="";this.library="default";this.family="";this.variant="";this._src="";this.rotate=0;this.autoWidth=false;this.swapOpacity=false;this.fixedWidth=false;this.fetchState={kind:"idle"};this.generation=0;this.onCustomSlotChange=()=>{this.syncCustomNodes()}}static{this.defaultStrings={...super.defaultStrings,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,iconLoadError:LYRA_DEFAULT_iconLoadError,iconSanitizerMissing:LYRA_DEFAULT_iconSanitizerMissing,iconTooLarge:LYRA_DEFAULT_iconTooLarge,loading:LYRA_DEFAULT_loading,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,styles,srOnly]}get name(){return this._name}set name(value){const old=this._name;this._name=value??"";this.requestUpdate("name",old)}get src(){return this._src}set src(value){const old=this._src;this._src=value??"";this.requestUpdate("src",old)}connectedCallback(){super.connectedCallback();this.errorAnnouncementSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this});this.stopLibrarySubscription??=subscribeIconLibrary(name=>{if(name===this.library)void this.load()});if(this.hasUpdated){queueMicrotask(()=>{if(this.isConnected)this.syncCustomNodes()});if(this.hasRemoteSource())this.scheduleAfterUpdate(()=>void this.load())}}disconnectedCallback(){this.generation++;this.releaseResourceLease();this.stopLibrarySubscription?.();this.stopLibrarySubscription=void 0;this.customContentObserver?.disconnect();this.customContentObserver=void 0;this.errorAnnouncementSink?.release();this.errorAnnouncementSink=void 0;if(this.fetchState.kind!=="idle")this.fetchState={kind:"idle"};super.disconnectedCallback()}updated(changed){super.updated(changed);if(changed.has("rotate")){const angle=finiteNumber(this.rotate??0,0);if(angle)this.style.setProperty("--lr-icon-rotate",`${angle}deg`);else this.style.removeProperty("--lr-icon-rotate")}this.applyRemoteA11y();this.syncCustomNodes();if(changed.has("src")||changed.has("library")||changed.has("name")||changed.has("family")||changed.has("variant")){this.scheduleAfterUpdate(()=>void this.load())}}syncCustomNodes(){if(this.fetchState.kind!=="idle")return;const svgEl=this.svgEl;if(!svgEl)return;svgEl.querySelectorAll("[data-lr-custom-copy]").forEach(node=>node.remove());this.customContentObserver?.disconnect();const slot=this.customSlot;if(!slot)return;for(const node of slot.assignedNodes({flatten:true})){const copy=this.cloneSvgNode(node);if(!copy)continue;copy.setAttribute("data-lr-custom-copy","");svgEl.append(copy)}this.observeCustomContent(slot)}observeCustomContent(slot){this.customContentObserver?.disconnect();if(!this.isConnected)return;const MutationObserverCtor=this.ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;this.customContentObserver??=new MutationObserverCtor(()=>{if(this.isConnected)this.syncCustomNodes()});for(const node of slot.assignedNodes({flatten:true})){if(node.nodeType===1){this.customContentObserver.observe(node,{attributes:true,childList:true,subtree:true})}}}cloneSvgNode(node){if(node.nodeType!==1)return null;const element=node;if(element.localName.includes("-"))return null;const copy=this.ownerDocument.createElementNS("http://www.w3.org/2000/svg",element.localName);for(const attribute of element.attributes){if(isUnsafeSvgCloneAttribute(attribute.name))continue;copy.setAttribute(attribute.name,attribute.value)}for(const child of element.childNodes){const childCopy=this.cloneSvgNode(child);if(childCopy)copy.append(childCopy);else if(child.nodeType===3){copy.append(this.ownerDocument.createTextNode(child.textContent??""))}}return copy}accessibleLabel(){return this.getAttribute("aria-label")??this.label}hasRemoteSource(){return Boolean(this.src||this.name&&this.library&&getIconLibrary(this.library))}releaseResourceLease(){this.resourceLease?.release();this.resourceLease=void 0}async load(){const generation=++this.generation;this.releaseResourceLease();const library=this.name&&this.library?getIconLibrary(this.library):void 0;if(!library&&!this.src){if(this.fetchState.kind!=="idle")this.fetchState={kind:"idle"};return}this.fetchState={kind:"loading"};let source=this.src;try{if(library){source=await library.resolver(this.name,this.family,this.variant);if(!this.isConnected||generation!==this.generation)return;if(typeof source!=="string")throw new TypeError("icon resolver did not return a URL")}}catch(error){await this.fail("load",generation,this.name,error);return}if(!source){if(this.isConnected&&generation===this.generation)this.fetchState={kind:"idle"};return}const safeSource=safeFetchUrl(source);if(!safeSource){await this.fail("load",generation,source,new Error("icon URL is not allowed"));return}const fetchTarget=resolveOwnerFetchTarget(this,safeSource);if(!fetchTarget){await this.fail("load",generation,safeSource,new Error("icon URL is not available"));return}let lease;try{lease=acquireSanitizedIconResource(fetchTarget);this.resourceLease=lease;const canonical=await lease.promise;if(!this.isConnected||generation!==this.generation)return;if(!canonical){this.fetchState={kind:"empty"};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource});return}const node=this.ownerDocument.importNode(canonical,true);library?.mutator?.(node);this.fetchState={kind:"loaded",node};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;this.emit("lr-load",{src:safeSource})}catch(error){if(isAbortError(error))return;const reason=error instanceof IconResourceError?error.reason:"load";await this.fail(reason,generation,safeSource,error)}finally{if(this.resourceLease===lease)this.resourceLease=void 0;lease?.release()}}async fail(reason,generation,src,error){if(!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",reason};await this.updateComplete;if(!this.isConnected||generation!==this.generation)return;if(isAccessibilityVisible(this)){this.errorAnnouncementSink?.announce(this.errorMessage(reason))}this.emit("lr-error",{src,error})}errorMessage(reason){if(reason==="sanitizer")return this.localize("iconSanitizerMissing");if(reason==="too-large")return this.localize("iconTooLarge");return this.localize("iconLoadError")}applyRemoteA11y(){const state2=this.fetchState;if(state2.kind!=="loaded")return;const label=this.accessibleLabel();state2.node.setAttribute("part","svg");state2.node.setAttribute("focusable","false");state2.node.setAttribute("aria-hidden",label?"false":"true");if(label)state2.node.setAttribute("aria-label",label);else state2.node.removeAttribute("aria-label");for(const use of state2.node.querySelectorAll("use")){const parts=new Set((use.getAttribute("part")??"").split(/\s+/).filter(Boolean));parts.add("use");use.setAttribute("part",[...parts].join(" "))}}renderBuiltIn(){const path=this.path||PATHS[this.name]||"";const accessibleLabel=this.accessibleLabel();return html`<svg part="svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden=${accessibleLabel?"false":"true"} aria-label=${accessibleLabel||nothing} focusable="false">${path?svg`<path d=${path}></path>`:nothing}</svg>${path?nothing:html`<slot @slotchange=${this.onCustomSlotChange}></slot>`}`}render(){const state2=this.fetchState;switch(state2.kind){case"loaded":return html`${state2.node}`;case"error":return html`<span part="error" class="sr-only" aria-hidden="true">${this.errorMessage(state2.reason)}</span>`;case"empty":return html`<span part="empty" aria-hidden="true"></span>`;case"loading":return html``;case"idle":default:return this.renderBuiltIn()}}}__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"name",null);__decorate([property()],LyraIcon.prototype,"path",void 0);__decorate([property()],LyraIcon.prototype,"label",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"library",void 0);__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"family",void 0);__decorate([property({reflect:true,useDefault:true})],LyraIcon.prototype,"variant",void 0);__decorate([property()],LyraIcon.prototype,"src",null);__decorate([property({type:Number,reflect:true,useDefault:true})],LyraIcon.prototype,"rotate",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"flip",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"canvas",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"auto-width"})],LyraIcon.prototype,"autoWidth",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"swap-opacity"})],LyraIcon.prototype,"swapOpacity",void 0);__decorate([property({reflect:true})],LyraIcon.prototype,"animation",void 0);__decorate([property({type:Boolean,reflect:true,attribute:"fixed-width"})],LyraIcon.prototype,"fixedWidth",void 0);__decorate([state()],LyraIcon.prototype,"fetchState",void 0);__decorate([query("svg")],LyraIcon.prototype,"svgEl",void 0);__decorate([query("slot")],LyraIcon.prototype,"customSlot",void 0);export{LyraIcon};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{srOnly}from"../../../internal/a11y.js";import{LyraElement}from"../../../internal/lyra-element.js";import{TextViewerTarget}from"../../../internal/text-viewer-target.js";import{fileIcon,folderIcon}from"../../../internal/icons.js";import{isAbortError,isResourceLimitError,LyraResourceLimitError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{buildQuoteAnchor,normalizeQuoteText,resolveTextQuote,scopeFromElement}from"../../../internal/text-quote.js";import{FILE_SIZE_UNIT_KEYS,formatFileSize}from"../../media/attachment-chip/attachment-chip.class.js";import{loadArchiveLibraryCached}from"./archive-loader.js";import{styles,virtualListHighlightStyles}from"./archive-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_archiveViewerEmpty,LYRA_DEFAULT_archiveViewerFile,LYRA_DEFAULT_archiveViewerFolder,LYRA_DEFAULT_archiveViewerUnavailable,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_fileSizeUnitB,LYRA_DEFAULT_fileSizeUnitGb,LYRA_DEFAULT_fileSizeUnitKb,LYRA_DEFAULT_fileSizeUnitMb,LYRA_DEFAULT_fileSizeUnitTb,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_ARCHIVE_ENTRIES=1e4;const MAX_ARCHIVE_UNCOMPRESSED_BYTES=100*1024*1024;class LyraArchiveViewerBase extends LyraElement{}const ArchiveTextViewerTargetBase=TextViewerTarget(LyraArchiveViewerBase);function measureArchiveEntry(file,remainingBytes,isCurrent){const stream=file.internalStream?.("uint8array");if(!stream){return Promise.reject(new LyraResourceLimitError("The archive entry size cannot be measured safely."))}return new Promise((resolve,reject)=>{let total=0;let settled=false;const fail=error=>{if(settled)return;settled=true;stream.pause?.();reject(error)};stream.on("data",chunk=>{if(!isCurrent()){const error=new Error("The operation was aborted.");error.name="AbortError";fail(error);return}total+=chunk.length;if(total>remainingBytes){fail(new LyraResourceLimitError("The expanded archive is too large."))}}).on("error",fail).on("end",()=>{if(settled)return;if(!isCurrent()){const error=new Error("The operation was aborted.");error.name="AbortError";fail(error);return}settled=true;resolve(total)});stream.resume()})}function archiveSelectionRange(viewer,contentRoot){const document=viewer.ownerDocument;const view=document.defaultView;const nestedRoot=contentRoot.getRootNode();const outerRoot=viewer.shadowRoot;const ShadowRootCtor=view?.ShadowRoot;const shadowRoots=[outerRoot,nestedRoot].filter((root,index,roots)=>ShadowRootCtor!==void 0&&root instanceof ShadowRootCtor&&roots.indexOf(root)===index);const globalSelection=view?.getSelection();if(globalSelection?.getComposedRanges){const[composed]=globalSelection.getComposedRanges({shadowRoots});if(composed&&(composed.startContainer!==composed.endContainer||composed.startOffset!==composed.endOffset)){const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}}const nestedSelection=nestedRoot.getSelection?.();const selection=nestedSelection??globalSelection??null;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}class LyraArchiveViewer extends ArchiveTextViewerTargetBase{constructor(){super(...arguments);this.src="";this.name="";this.fetchState={kind:"idle"};this.archiveSearchMatches=[];this.archiveSearchActiveIndex=-1;this.generation=0;this.archiveSearchQuery="";this.loadLibrary=loadArchiveLibraryCached;this.archiveSelectionRoot=null;this.styledVirtualListRoot=null;this.archiveNestedUpdatePending=false;this.archiveEntryKey=item=>item.name;this.announcements=new ViewerAnnouncementController(this);this.renderEntry=item=>{const entry=item;const kind=this.localize(entry.dir?"archiveViewerFolder":"archiveViewerFile");return html`<div part="entry" data-dir=${entry.dir?"true":"false"}><span part="entry-icon">${entry.dir?folderIcon():fileIcon()}</span><span class="sr-only">${kind}</span><span id=${entry.name} part=${entry.dir?"entry-name entry-name-dir":"entry-name"} dir="auto" title=${entry.name}>${entry.name}</span>${entry.dir?nothing:html`<span part="entry-size" dir="auto">${formatFileSize(entry.size,unit=>this.localize(FILE_SIZE_UNIT_KEYS[unit]),(value,fractionDigits)=>getNumberFormat(this.effectiveLocale,{minimumFractionDigits:fractionDigits,maximumFractionDigits:fractionDigits}).format(value))}</span>`}</div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,archiveViewerEmpty:LYRA_DEFAULT_archiveViewerEmpty,archiveViewerFile:LYRA_DEFAULT_archiveViewerFile,archiveViewerFolder:LYRA_DEFAULT_archiveViewerFolder,archiveViewerUnavailable:LYRA_DEFAULT_archiveViewerUnavailable,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,styles,srOnly]}async search(query){this.archiveSearchQuery=query;this.recomputeArchiveSearch();await this.updateComplete;this.scrollActiveArchiveMatch();return this.archiveSearchMatches.length}async searchNext(){if(!this.archiveSearchMatches.length)return false;this.archiveSearchActiveIndex=(this.archiveSearchActiveIndex+1)%this.archiveSearchMatches.length;this.emitArchiveSearchChange();await this.updateComplete;this.scrollActiveArchiveMatch();return true}async searchPrevious(){if(!this.archiveSearchMatches.length)return false;this.archiveSearchActiveIndex=(this.archiveSearchActiveIndex-1+this.archiveSearchMatches.length)%this.archiveSearchMatches.length;this.emitArchiveSearchChange();await this.updateComplete;this.scrollActiveArchiveMatch();return true}clearSearch(){this.archiveSearchQuery="";this.archiveSearchMatches=[];this.archiveSearchActiveIndex=-1;this.emitArchiveSearchChange()}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));this.syncArchiveNestedRoot();if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src)this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.archiveSelectionCleanup?.();this.archiveSelectionCleanup=void 0;this.archiveSelectionRoot=null;this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}textContentRoot(){return this.archiveVirtualList()?.shadowRoot?.querySelector('[part="spacer"]')??null}async applyAnchor(anchor){if(this.fetchState.kind!=="loaded")return false;let index=-1;if(anchor.kind==="fragment"){index=this.fetchState.entries.findIndex(entry=>entry.name===anchor.id)}else if(anchor.kind==="text-quote"){const probe=this.ownerDocument.createElement("span");index=this.fetchState.entries.findIndex(entry=>{probe.textContent=entry.name;return resolveTextQuote(scopeFromElement(probe),anchor,this.effectiveLocale)!==null})}if(index<0)return false;const list=this.archiveVirtualList();if(!list)return false;list.scrollToIndex(index,{align:"auto",behavior:"auto"});if(!await this.waitForArchiveRow(list,index))return false;this.requestUpdate();await this.updateComplete;const applyTextAnchor=ArchiveTextViewerTargetBase.prototype.applyAnchor;return applyTextAnchor.call(this,anchor)}computeSelectionAnchor(range){const entryName=node=>{const elementNode=this.ownerDocument.defaultView?.Node.ELEMENT_NODE??1;const element=node.nodeType===elementNode?node:node.parentElement;return element?.closest('[part~="entry-name"]')??null};const start=entryName(range.startContainer);const end=entryName(range.endContainer);if(!start||start!==end)return null;return buildQuoteAnchor(range,scopeFromElement(start))}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new Error("Unsafe archive source URL");this.fetchState={kind:"error",message:this.localize("documentPreviewUrlNotAllowed")};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);if(!this.isConnected||generation!==this.generation)return;const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new Error("Archive renderer unavailable");this.fetchState={kind:"error",message:this.localize("archiveViewerUnavailable")};this.emit("lr-render-error",{error});return}const buffer=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;const zip=await library.loadAsync(buffer);if(!this.isConnected||generation!==this.generation)return;const entries=[];const fallbackSizes=[];let totalUncompressed=0;zip.forEach((_path,file)=>{if(entries.length>=MAX_ARCHIVE_ENTRIES)throw new LyraResourceLimitError;const declaredSize=file._data?.uncompressedSize;const hasDeclaredSize=Number.isFinite(declaredSize);if(hasDeclaredSize&&declaredSize>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError;totalUncompressed+=hasDeclaredSize?declaredSize:0;if(totalUncompressed>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError;const entry={name:file.name,dir:file.dir,size:hasDeclaredSize?declaredSize:0};entries.push(entry);if(!file.dir&&!hasDeclaredSize)fallbackSizes.push({entry,file})});for(const fallback of fallbackSizes){const size=await measureArchiveEntry(fallback.file,MAX_ARCHIVE_UNCOMPRESSED_BYTES-totalUncompressed,()=>this.isConnected&&generation===this.generation);if(!this.isConnected||generation!==this.generation)return;fallback.entry.size=size;totalUncompressed+=size;if(totalUncompressed>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError}this.fetchState={kind:"loaded",entries};if(this.archiveSearchQuery)this.recomputeArchiveSearch()}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}stopVirtualListEvent(event){event.stopPropagation();if(this.archiveNestedUpdatePending)return;this.archiveNestedUpdatePending=true;queueMicrotask(()=>{this.archiveNestedUpdatePending=false;if(this.isConnected)this.requestUpdate()})}archiveVirtualList(){return this.renderRoot.querySelector("lr-virtual-list")}async waitForArchiveRow(list,index){const view=this.ownerDocument.defaultView;for(let attempt=0;attempt<5;attempt++){await list.updateComplete;if(list.shadowRoot?.querySelector(`[data-row-index="${index}"]`))return true;if(!view)return false;await new Promise(resolve=>view.requestAnimationFrame(()=>resolve()))}return false}syncArchiveNestedRoot(){const root=this.textContentRoot();if(root!==this.archiveSelectionRoot){this.unbindTextSelection();this.archiveSelectionCleanup?.();this.archiveSelectionCleanup=void 0;this.archiveSelectionRoot=root;if(root){const emitSelection=()=>{const range=archiveSelectionRange(this,root);if(!range||!root.contains(range.startContainer)||!root.contains(range.endContainer))return;const text=normalizeQuoteText(range.toString());if(!text)return;const anchor=this.computeSelectionAnchor(range);const rects=Array.from(range.getClientRects());this.emit("lr-text-select",{text,anchor,rects})};root.addEventListener("pointerup",emitSelection);root.addEventListener("keyup",emitSelection);this.archiveSelectionCleanup=()=>{root.removeEventListener("pointerup",emitSelection);root.removeEventListener("keyup",emitSelection)}}}const listRoot=this.archiveVirtualList()?.shadowRoot??null;if(listRoot&&listRoot!==this.styledVirtualListRoot){const existing=listRoot.querySelector("style[data-lr-archive-highlight-styles]");if(existing){this.styledVirtualListRoot=listRoot}else{const style=this.ownerDocument.createElement("style");style.dataset["lrArchiveHighlightStyles"]="";style.textContent=virtualListHighlightStyles.cssText;listRoot.append(style);this.styledVirtualListRoot=listRoot}}if(root){for(const mark of root.querySelectorAll("mark[data-lr-highlight-tone]")){if(!mark.hasAttribute("part"))mark.setAttribute("part","highlight")}}}recomputeArchiveSearch(){const entries=this.fetchState.kind==="loaded"?this.fetchState.entries:[];const query=this.archiveSearchQuery.trim().toLocaleLowerCase(this.effectiveLocale);this.archiveSearchMatches=query?entries.filter(entry=>entry.name.toLocaleLowerCase(this.effectiveLocale).includes(query)):[];this.archiveSearchActiveIndex=this.archiveSearchMatches.length>0?0:-1;this.emitArchiveSearchChange()}emitArchiveSearchChange(){this.emit("lr-search-change",{query:this.archiveSearchQuery,matchCount:this.archiveSearchMatches.length,activeIndex:this.archiveSearchActiveIndex})}scrollActiveArchiveMatch(){if(this.fetchState.kind!=="loaded")return;const match=this.archiveSearchMatches[this.archiveSearchActiveIndex];if(!match)return;const index=this.fetchState.entries.indexOf(match);const list=this.renderRoot.querySelector("lr-virtual-list");if(index>=0)list?.scrollToIndex(index,{behavior:"auto"})}renderBody(){switch(this.fetchState.kind){case"loaded":return this.fetchState.entries.length?html`<lr-virtual-list exportparts="entry:entry, entry-icon:entry-icon, entry-name:entry-name, entry-name-dir:entry-name-dir, entry-size:entry-size, highlight:highlight" .items=${this.fetchState.entries} .renderItem=${this.renderEntry} .keyFunction=${this.archiveEntryKey} .activeId=${this.archiveSearchMatches[this.archiveSearchActiveIndex]?.name??""} @lr-visible-range-changed=${this.stopVirtualListEvent} @lr-scroll=${this.stopVirtualListEvent}></lr-virtual-list>`:html`<p class="empty-note">${this.localize("archiveViewerEmpty")}</p>`;case"loading":return html`<div part="spinner"><span class="sr-only">${this.localize("loadingDocument")}</span></div>`;case"error":return html`<div part="error">${this.fetchState.message}</div>`;case"idle":default:return html`<p class="empty-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}}render(){const label=this.getAttribute("aria-label")||this.name;return label?html`<div part="base" role="region" aria-label=${label}><div part="body">${this.renderBody()}</div>${this.renderAnchorLiveRegion()}</div>`:html`<div part="base"><div part="body">${this.renderBody()}</div>${this.renderAnchorLiveRegion()}</div>`}}__decorate([property()],LyraArchiveViewer.prototype,"src",void 0);__decorate([property()],LyraArchiveViewer.prototype,"name",void 0);__decorate([state()],LyraArchiveViewer.prototype,"fetchState",void 0);__decorate([state()],LyraArchiveViewer.prototype,"archiveSearchMatches",void 0);__decorate([state()],LyraArchiveViewer.prototype,"archiveSearchActiveIndex",void 0);export{LyraArchiveViewer};
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{srOnly}from"../../../internal/a11y.js";import{LyraElement}from"../../../internal/lyra-element.js";import{TextViewerTarget}from"../../../internal/text-viewer-target.js";import{fileIcon,folderIcon}from"../../../internal/icons.js";import{isAbortError,isResourceLimitError,LyraResourceLimitError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{buildQuoteAnchor,normalizeQuoteText,resolveTextQuote,scopeFromElement}from"../../../internal/text-quote.js";import{FILE_SIZE_UNIT_KEYS,formatFileSize}from"../../media/attachment-chip/attachment-chip.class.js";import{loadArchiveLibraryCached}from"./archive-loader.js";import{styles,virtualListHighlightStyles}from"./archive-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_archiveViewerEmpty,LYRA_DEFAULT_archiveViewerFile,LYRA_DEFAULT_archiveViewerFolder,LYRA_DEFAULT_archiveViewerUnavailable,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_fileSizeUnitB,LYRA_DEFAULT_fileSizeUnitGb,LYRA_DEFAULT_fileSizeUnitKb,LYRA_DEFAULT_fileSizeUnitMb,LYRA_DEFAULT_fileSizeUnitTb,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_ARCHIVE_ENTRIES=1e4;const MAX_ARCHIVE_UNCOMPRESSED_BYTES=100*1024*1024;class LyraArchiveViewerBase extends LyraElement{}const ArchiveTextViewerTargetBase=TextViewerTarget(LyraArchiveViewerBase);function measureArchiveEntry(file,remainingBytes,isCurrent){const stream=file.internalStream?.("uint8array");if(!stream){return Promise.reject(new LyraResourceLimitError("The archive entry size cannot be measured safely."))}return new Promise((resolve,reject)=>{let total=0;let settled=false;const fail=error=>{if(settled)return;settled=true;stream.pause?.();reject(error)};stream.on("data",chunk=>{if(!isCurrent()){const error=new Error("The operation was aborted.");error.name="AbortError";fail(error);return}total+=chunk.length;if(total>remainingBytes){fail(new LyraResourceLimitError("The expanded archive is too large."))}}).on("error",fail).on("end",()=>{if(settled)return;if(!isCurrent()){const error=new Error("The operation was aborted.");error.name="AbortError";fail(error);return}settled=true;resolve(total)});stream.resume()})}function archiveSelectionRange(viewer,contentRoot){const document=viewer.ownerDocument;const view=document.defaultView;const nestedRoot=contentRoot.getRootNode();const outerRoot=viewer.shadowRoot;const ShadowRootCtor=view?.ShadowRoot;const shadowRoots=[outerRoot,nestedRoot].filter((root,index,roots)=>ShadowRootCtor!==void 0&&root instanceof ShadowRootCtor&&roots.indexOf(root)===index);const globalSelection=view?.getSelection();if(globalSelection?.getComposedRanges){const[composed]=globalSelection.getComposedRanges({shadowRoots});if(composed&&(composed.startContainer!==composed.endContainer||composed.startOffset!==composed.endOffset)){const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}}const nestedSelection=nestedRoot.getSelection?.();const selection=nestedSelection??globalSelection??null;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}class LyraArchiveViewer extends ArchiveTextViewerTargetBase{constructor(){super(...arguments);this.src="";this.name="";this.fetchState={kind:"idle"};this.archiveSearchMatches=[];this.archiveSearchActiveIndex=-1;this.generation=0;this.archiveSearchQuery="";this.loadLibrary=loadArchiveLibraryCached;this.archiveSelectionRoot=null;this.styledVirtualListRoot=null;this.archiveNestedUpdatePending=false;this.archiveEntryKey=item=>item.name;this.announcements=new ViewerAnnouncementController(this);this.renderEntry=item=>{const entry=item;const kind=this.localize(entry.dir?"archiveViewerFolder":"archiveViewerFile");return html`<div part="entry" data-dir=${entry.dir?"true":"false"}><span part="entry-icon">${entry.dir?folderIcon():fileIcon()}</span><span class="sr-only">${kind}</span><span part=${entry.dir?"entry-name entry-name-dir":"entry-name"} dir="auto" title=${entry.name}>${entry.name}</span>${entry.dir?nothing:html`<span part="entry-size" dir="auto">${formatFileSize(entry.size,unit=>this.localize(FILE_SIZE_UNIT_KEYS[unit]),(value,fractionDigits)=>getNumberFormat(this.effectiveLocale,{minimumFractionDigits:fractionDigits,maximumFractionDigits:fractionDigits}).format(value))}</span>`}</div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,archiveViewerEmpty:LYRA_DEFAULT_archiveViewerEmpty,archiveViewerFile:LYRA_DEFAULT_archiveViewerFile,archiveViewerFolder:LYRA_DEFAULT_archiveViewerFolder,archiveViewerUnavailable:LYRA_DEFAULT_archiveViewerUnavailable,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,fileSizeUnitB:LYRA_DEFAULT_fileSizeUnitB,fileSizeUnitGb:LYRA_DEFAULT_fileSizeUnitGb,fileSizeUnitKb:LYRA_DEFAULT_fileSizeUnitKb,fileSizeUnitMb:LYRA_DEFAULT_fileSizeUnitMb,fileSizeUnitTb:LYRA_DEFAULT_fileSizeUnitTb,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,styles,srOnly]}async search(query){this.archiveSearchQuery=query;this.recomputeArchiveSearch();await this.updateComplete;this.scrollActiveArchiveMatch();return this.archiveSearchMatches.length}async searchNext(){if(!this.archiveSearchMatches.length)return false;this.archiveSearchActiveIndex=(this.archiveSearchActiveIndex+1)%this.archiveSearchMatches.length;this.emitArchiveSearchChange();await this.updateComplete;this.scrollActiveArchiveMatch();return true}async searchPrevious(){if(!this.archiveSearchMatches.length)return false;this.archiveSearchActiveIndex=(this.archiveSearchActiveIndex-1+this.archiveSearchMatches.length)%this.archiveSearchMatches.length;this.emitArchiveSearchChange();await this.updateComplete;this.scrollActiveArchiveMatch();return true}clearSearch(){this.archiveSearchQuery="";this.archiveSearchMatches=[];this.archiveSearchActiveIndex=-1;this.emitArchiveSearchChange()}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));this.syncArchiveNestedRoot();if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src)this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.archiveSelectionCleanup?.();this.archiveSelectionCleanup=void 0;this.archiveSelectionRoot=null;this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}textContentRoot(){return this.archiveVirtualList()?.shadowRoot?.querySelector('[part="spacer"]')??null}async applyAnchor(anchor){if(this.fetchState.kind!=="loaded")return false;let index=-1;let resolvedName;if(anchor.kind==="fragment"){index=this.fetchState.entries.findIndex(entry=>entry.name===anchor.id);resolvedName=this.fetchState.entries[index]?.name}else if(anchor.kind==="text-quote"){const probe=this.ownerDocument.createElement("span");index=this.fetchState.entries.findIndex(entry=>{probe.textContent=entry.name;return resolveTextQuote(scopeFromElement(probe),anchor,this.effectiveLocale)!==null})}if(index<0)return false;const list=this.archiveVirtualList();if(!list)return false;list.scrollToIndex(index,{align:"auto",behavior:"auto"});if(!await this.waitForArchiveRow(list,index))return false;this.requestUpdate();await this.updateComplete;if(anchor.kind==="fragment"){const root=this.textContentRoot();const target=root?Array.from(root.querySelectorAll('[part~="entry-name"]')).find(el=>el.textContent===resolvedName):null;target?.scrollIntoView?.({block:"nearest",behavior:"auto"});return true}const applyTextAnchor=ArchiveTextViewerTargetBase.prototype.applyAnchor;return applyTextAnchor.call(this,anchor)}computeSelectionAnchor(range){const entryName=node=>{const elementNode=this.ownerDocument.defaultView?.Node.ELEMENT_NODE??1;const element=node.nodeType===elementNode?node:node.parentElement;return element?.closest('[part~="entry-name"]')??null};const start=entryName(range.startContainer);const end=entryName(range.endContainer);if(!start||start!==end)return null;return buildQuoteAnchor(range,scopeFromElement(start))}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new Error("Unsafe archive source URL");this.fetchState={kind:"error",message:this.localize("documentPreviewUrlNotAllowed")};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);if(!this.isConnected||generation!==this.generation)return;const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new Error("Archive renderer unavailable");this.fetchState={kind:"error",message:this.localize("archiveViewerUnavailable")};this.emit("lr-render-error",{error});return}const buffer=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;const zip=await library.loadAsync(buffer);if(!this.isConnected||generation!==this.generation)return;const entries=[];const fallbackSizes=[];let totalUncompressed=0;zip.forEach((_path,file)=>{if(entries.length>=MAX_ARCHIVE_ENTRIES)throw new LyraResourceLimitError;const declaredSize=file._data?.uncompressedSize;const hasDeclaredSize=Number.isFinite(declaredSize);if(hasDeclaredSize&&declaredSize>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError;totalUncompressed+=hasDeclaredSize?declaredSize:0;if(totalUncompressed>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError;const entry={name:file.name,dir:file.dir,size:hasDeclaredSize?declaredSize:0};entries.push(entry);if(!file.dir&&!hasDeclaredSize)fallbackSizes.push({entry,file})});for(const fallback of fallbackSizes){const size=await measureArchiveEntry(fallback.file,MAX_ARCHIVE_UNCOMPRESSED_BYTES-totalUncompressed,()=>this.isConnected&&generation===this.generation);if(!this.isConnected||generation!==this.generation)return;fallback.entry.size=size;totalUncompressed+=size;if(totalUncompressed>MAX_ARCHIVE_UNCOMPRESSED_BYTES)throw new LyraResourceLimitError}this.fetchState={kind:"loaded",entries};if(this.archiveSearchQuery)this.recomputeArchiveSearch()}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}stopVirtualListEvent(event){event.stopPropagation();if(this.archiveNestedUpdatePending)return;this.archiveNestedUpdatePending=true;queueMicrotask(()=>{this.archiveNestedUpdatePending=false;if(this.isConnected)this.requestUpdate()})}archiveVirtualList(){return this.renderRoot.querySelector("lr-virtual-list")}async waitForArchiveRow(list,index){const view=this.ownerDocument.defaultView;for(let attempt=0;attempt<5;attempt++){await list.updateComplete;if(list.shadowRoot?.querySelector(`[data-row-index="${index}"]`))return true;if(!view)return false;await new Promise(resolve=>view.requestAnimationFrame(()=>resolve()))}return false}syncArchiveNestedRoot(){const root=this.textContentRoot();if(root!==this.archiveSelectionRoot){this.unbindTextSelection();this.archiveSelectionCleanup?.();this.archiveSelectionCleanup=void 0;this.archiveSelectionRoot=root;if(root){const emitSelection=()=>{const range=archiveSelectionRange(this,root);if(!range||!root.contains(range.startContainer)||!root.contains(range.endContainer))return;const text=normalizeQuoteText(range.toString());if(!text)return;const anchor=this.computeSelectionAnchor(range);const rects=Array.from(range.getClientRects());this.emit("lr-text-select",{text,anchor,rects})};root.addEventListener("pointerup",emitSelection);root.addEventListener("keyup",emitSelection);this.archiveSelectionCleanup=()=>{root.removeEventListener("pointerup",emitSelection);root.removeEventListener("keyup",emitSelection)}}}const listRoot=this.archiveVirtualList()?.shadowRoot??null;if(listRoot&&listRoot!==this.styledVirtualListRoot){const existing=listRoot.querySelector("style[data-lr-archive-highlight-styles]");if(existing){this.styledVirtualListRoot=listRoot}else{const style=this.ownerDocument.createElement("style");style.dataset["lrArchiveHighlightStyles"]="";style.textContent=virtualListHighlightStyles.cssText;listRoot.append(style);this.styledVirtualListRoot=listRoot}}if(root){for(const mark of root.querySelectorAll("mark[data-lr-highlight-tone]")){if(!mark.hasAttribute("part"))mark.setAttribute("part","highlight")}}}recomputeArchiveSearch(){const entries=this.fetchState.kind==="loaded"?this.fetchState.entries:[];const query=this.archiveSearchQuery.trim().toLocaleLowerCase(this.effectiveLocale);this.archiveSearchMatches=query?entries.filter(entry=>entry.name.toLocaleLowerCase(this.effectiveLocale).includes(query)):[];this.archiveSearchActiveIndex=this.archiveSearchMatches.length>0?0:-1;this.emitArchiveSearchChange()}emitArchiveSearchChange(){this.emit("lr-search-change",{query:this.archiveSearchQuery,matchCount:this.archiveSearchMatches.length,activeIndex:this.archiveSearchActiveIndex})}scrollActiveArchiveMatch(){if(this.fetchState.kind!=="loaded")return;const match=this.archiveSearchMatches[this.archiveSearchActiveIndex];if(!match)return;const index=this.fetchState.entries.indexOf(match);const list=this.renderRoot.querySelector("lr-virtual-list");if(index>=0)list?.scrollToIndex(index,{behavior:"auto"})}renderBody(){switch(this.fetchState.kind){case"loaded":return this.fetchState.entries.length?html`<lr-virtual-list exportparts="entry:entry, entry-icon:entry-icon, entry-name:entry-name, entry-name-dir:entry-name-dir, entry-size:entry-size, highlight:highlight" .items=${this.fetchState.entries} .renderItem=${this.renderEntry} .keyFunction=${this.archiveEntryKey} .activeId=${this.archiveSearchMatches[this.archiveSearchActiveIndex]?.name??""} @lr-visible-range-changed=${this.stopVirtualListEvent} @lr-scroll=${this.stopVirtualListEvent}></lr-virtual-list>`:html`<p class="empty-note">${this.localize("archiveViewerEmpty")}</p>`;case"loading":return html`<div part="spinner"><span class="sr-only">${this.localize("loadingDocument")}</span></div>`;case"error":return html`<div part="error">${this.fetchState.message}</div>`;case"idle":default:return html`<p class="empty-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}}render(){const label=this.getAttribute("aria-label")||this.name;return label?html`<div part="base" role="region" aria-label=${label}><div part="body">${this.renderBody()}</div>${this.renderAnchorLiveRegion()}</div>`:html`<div part="base"><div part="body">${this.renderBody()}</div>${this.renderAnchorLiveRegion()}</div>`}}__decorate([property()],LyraArchiveViewer.prototype,"src",void 0);__decorate([property()],LyraArchiveViewer.prototype,"name",void 0);__decorate([state()],LyraArchiveViewer.prototype,"fetchState",void 0);__decorate([state()],LyraArchiveViewer.prototype,"archiveSearchMatches",void 0);__decorate([state()],LyraArchiveViewer.prototype,"archiveSearchActiveIndex",void 0);export{LyraArchiveViewer};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{chevronIcon}from"../../../internal/icons.js";import{srOnly}from"../../../internal/a11y.js";import{Announcer}from"../../../internal/announcer.js";import{announceSearchResult}from"../../../internal/viewer-search.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{getEpubJs}from"./ebook-loader.js";import{assertEpubArchiveWithinLimits}from"./epub-resource-guard.js";import{styles}from"./ebook-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_ebookViewerLoadError,LYRA_DEFAULT_ebookViewerNextChapter,LYRA_DEFAULT_ebookViewerPreviousChapter,LYRA_DEFAULT_ebookViewerRegionLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_next,LYRA_DEFAULT_open,LYRA_DEFAULT_previous,LYRA_DEFAULT_viewerSearchActiveMatch,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings.generated.js";const MAX_TOC_ITEMS=1e4;const MAX_TOC_DEPTH=100;const MAX_SEARCH_MATCHES=1e4;const TONE_FILL_TOKEN={accent:{token:"--lr-color-brand-quiet",fallback:"#ddf4ff"},success:{token:"--lr-color-success-quiet",fallback:"#dafbe1"},warning:{token:"--lr-color-warning-quiet",fallback:"#fff8c5"},danger:{token:"--lr-color-danger-quiet",fallback:"#ffebe9"},neutral:{token:"--lr-color-surface-raised",fallback:"#f6f8fa"}};const SEARCH_MATCH_FILL_TOKEN={token:"--lr-color-warning",fallback:"#9a6700"};class LyraEbookViewerBase extends LyraElement{}class LyraEbookViewer extends DocumentAnchorTarget(LyraEbookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.accessibleLabel="";this.location="";this.anchorKinds=["cfi","text-quote"];this.ebookState={kind:"idle"};this.searchMatches=[];this.searchActiveIndex=-1;this.mountRef=createRef();this.generation=0;this.searchQuery="";this.searchGeneration=0;this.anchorOperationGeneration=0;this.paintedHighlightCfis=[];this.announcements=new ViewerAnnouncementController(this);this.announcer=new Announcer({onFlush:text=>this.announcements.announcePolite(text)});this.previous=()=>{this.runRenditionNavigation("previous")};this.next=()=>{this.runRenditionNavigation("next")}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,ebookViewerLoadError:LYRA_DEFAULT_ebookViewerLoadError,ebookViewerNextChapter:LYRA_DEFAULT_ebookViewerNextChapter,ebookViewerPreviousChapter:LYRA_DEFAULT_ebookViewerPreviousChapter,ebookViewerRegionLabel:LYRA_DEFAULT_ebookViewerRegionLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,next:LYRA_DEFAULT_next,open:LYRA_DEFAULT_open,previous:LYRA_DEFAULT_previous,viewerSearchActiveMatch:LYRA_DEFAULT_viewerSearchActiveMatch,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.styles=[LyraElement.styles,styles,srOnly]}updated(changed){super.updated(changed);this.announcements.transition("load",this.ebookState.kind,this.ebookState.kind==="error"?this.ebookState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});if(changed.has("location")){const fromRelocated=this.relocatedLocation===this.location;this.relocatedLocation=void 0;if(!fromRelocated&&this.rendition&&this.location)this.displayLocation(this.location)}if((changed.has("highlights")||changed.has("activeHighlightId"))&&this.rendition){this.repaintHighlights()}}connectedCallback(){super.connectedCallback();const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.connect();if(this.hasUpdated&&this.src.trim())this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.anchorOperationGeneration++;this.announcer.cancel();this.announcements.disconnect();this.teardown();this.ebookState={kind:"idle"};super.disconnectedCallback()}adoptedCallback(){const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.adopted()}teardown(){this.book?.destroy();this.book=void 0;this.rendition=void 0;this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchAnnotationCfi=void 0;this.paintedHighlightCfis=[]}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();this.teardown();if(!this.src.trim()){this.ebookState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.ebookState={kind:"loading"};let data;let factory;try{[data,factory]=await Promise.all([fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0).then(response=>{if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);return readResponseArrayBuffer(response)}),getEpubJs()]);if(!this.isConnected||generation!==this.generation)return;await assertEpubArchiveWithinLimits(data,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"ebookViewerLoadError")};this.emit("lr-render-error",{error});return}if(!factory){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}const mount=this.mountRef.value;if(!mount){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}let candidateBook;try{const book=factory(data);candidateBook=book;const rendition=book.renderTo(mount,{width:"100%",height:"100%"});await book.ready;if(!this.isConnected||generation!==this.generation){book.destroy();return}await rendition.display(this.location||void 0);if(!this.isConnected||generation!==this.generation){book.destroy();return}rendition.on("relocated",loc=>{const cfi=loc?.start?.cfi??"";const href=loc?.start?.href??"";if(!cfi||cfi===this.location)return;this.relocatedLocation=cfi;this.location=cfi;this.emit("lr-location-change",{cfi,href})});rendition.on("selected",(cfiRange,contents)=>{const selection=contents?.window?.getSelection?.();const text=selection?String(selection.toString()):"";if(!text.trim())return;const rects=selection&&selection.rangeCount>0?Array.from(selection.getRangeAt(0).getClientRects()):[];this.emit("lr-text-select",{text,anchor:{kind:"cfi",cfi:cfiRange},rects})});this.book=book;this.rendition=rendition;candidateBook=void 0;this.ebookState={kind:"ready"};this.repaintHighlights()}catch(error){candidateBook?.destroy();if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.ebookState={kind:"error",message};this.emit("lr-render-error",{error})}reportRenditionFailure(error,rendition,generation){if(!this.isConnected||generation!==this.generation||rendition!==this.rendition)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}displayLocation(location){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{void Promise.resolve(rendition.display(location)).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}runRenditionNavigation(action){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{const task=action==="previous"?rendition.prev():rendition.next();void Promise.resolve(task).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}async getToc(){const book=this.book;if(!book)return[];await book.ready;if(this.book!==book)return[];const items=[];const seen=new WeakSet;const stack=(book.navigation?.toc??[]).map(entry=>({entry,level:1})).reverse();while(stack.length>0&&items.length<MAX_TOC_ITEMS){const current=stack.pop();const{entry,level}=current;if(!entry||typeof entry!=="object"||seen.has(entry))continue;seen.add(entry);items.push({id:entry.id||entry.href,label:String(entry.label??"").trim(),href:entry.href,level});if(level>=MAX_TOC_DEPTH||!Array.isArray(entry.subitems))continue;for(let index=entry.subitems.length-1;index>=0;index--){stack.push({entry:entry.subitems[index],level:level+1})}}return items}async scrollToAnchor(target){const operation=++this.anchorOperationGeneration;try{return await super.scrollToAnchor(target)}catch(error){if(operation!==this.anchorOperationGeneration)return false;const rendition=this.rendition;if(rendition)this.reportRenditionFailure(error,rendition,this.generation);this.emit("lr-anchor-result",{found:false});return false}}async applyAnchor(anchor){const rendition=this.rendition;const operation=this.anchorOperationGeneration;if(!rendition)return false;if(anchor.kind==="cfi"){if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(anchor.cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}if(anchor.kind==="text-quote"){const cfi=await this.findTextQuoteCfi(anchor.quote);if(!cfi)return false;if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}return false}async findTextQuoteCfi(quote){const book=this.book;const generation=this.generation;if(!book)return null;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(!this.isConnected||generation!==this.generation||this.book!==book)return null;const results=await item.find(quote)??[];if(!this.isConnected||generation!==this.generation||this.book!==book)return null;if(results.length)return results[0].cfi}catch{continue}finally{if(loaded)item.unload()}}return null}repaintHighlights(){if(!this.rendition)return;for(const cfi of this.paintedHighlightCfis)this.rendition.annotations.remove(cfi,"highlight");this.paintedHighlightCfis=[];for(const highlight of this.highlights){if(highlight.anchor.kind!=="cfi")continue;const cfi=highlight.anchor.cfi;const tone=highlight.tone??"accent";this.rendition.annotations.highlight(cfi,{id:highlight.id},()=>this.emit("lr-highlight-activate",{id:highlight.id}),`lr-hl-${tone}`,this.resolveHighlightFill(TONE_FILL_TOKEN[tone]));this.paintedHighlightCfis.push(cfi)}}async search(query){const generation=++this.searchGeneration;this.searchQuery=query;this.clearSearchAnnotation();if(!this.book||!query.trim()){this.searchMatches=[];this.searchActiveIndex=-1;this.emitSearchChange();return 0}const matches=[];const book=this.book;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){if(generation!==this.searchGeneration)return this.searchMatches.length;let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;const results=await item.find(query)??[];if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;for(const r of results){if(matches.length>=MAX_SEARCH_MATCHES)break;matches.push({cfi:r.cfi,excerpt:r.excerpt??""})}}catch{continue}finally{if(loaded)item.unload()}if(matches.length>=MAX_SEARCH_MATCHES)break}if(generation!==this.searchGeneration)return this.searchMatches.length;this.searchMatches=matches;this.searchActiveIndex=matches.length>0?0:-1;this.emitSearchChange();if(this.searchActiveIndex>=0)await this.showSearchMatch(this.searchActiveIndex,generation);return matches.length}async searchNext(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex+1)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}async searchPrevious(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex-1+this.searchMatches.length)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}clearSearch(){this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.clearSearchAnnotation();this.emit("lr-search-change",{query:"",matchCount:0,activeIndex:-1})}clearSearchAnnotation(){if(this.searchAnnotationCfi)this.rendition?.annotations.remove(this.searchAnnotationCfi,"highlight");this.searchAnnotationCfi=void 0}async showSearchMatch(index,generation=this.searchGeneration){const match=this.searchMatches[index];const rendition=this.rendition;if(!match||!rendition||generation!==this.searchGeneration)return false;this.clearSearchAnnotation();try{await rendition.display(match.cfi)}catch(error){if(generation===this.searchGeneration&&rendition===this.rendition){this.reportRenditionFailure(error,rendition,this.generation)}return false}if(generation!==this.searchGeneration||rendition!==this.rendition||this.searchMatches[index]!==match)return false;try{rendition.annotations.highlight(match.cfi,{},void 0,"lr-ebook-search",this.resolveHighlightFill(SEARCH_MATCH_FILL_TOKEN))}catch(error){this.reportRenditionFailure(error,rendition,this.generation);return false}this.searchAnnotationCfi=match.cfi;return true}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.searchActiveIndex});const numberFormat=getNumberFormat(this.effectiveLocale);announceSearchResult((key,fallback,values)=>this.localize(key,fallback,values?Object.fromEntries(Object.entries(values).map(([name,value])=>[name,typeof value==="number"?numberFormat.format(value):value])):void 0),this.announcer,this.searchMatches.length,this.searchActiveIndex)}resolveHighlightFill({token,fallback}){const value=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue(token).trim()??"";return{fill:value||fallback}}renderStatus(){if(this.ebookState.kind==="loading"){return html`<p class="status-note">${this.localize("loadingDocument")}</p>`}if(this.ebookState.kind==="error")return html`<div part="error">${this.ebookState.message}</div>`;if(this.ebookState.kind==="idle"){return html`<p class="status-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}return nothing}render(){const disabled=this.ebookState.kind!=="ready";return html`
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import{LyraElement}from"../../../internal/lyra-element.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{chevronIcon}from"../../../internal/icons.js";import{srOnly}from"../../../internal/a11y.js";import{Announcer}from"../../../internal/announcer.js";import{announceSearchResult}from"../../../internal/viewer-search.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{getEpubJs}from"./ebook-loader.js";import{assertEpubArchiveWithinLimits}from"./epub-resource-guard.js";import{styles}from"./ebook-viewer.styles.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_ebookViewerLoadError,LYRA_DEFAULT_ebookViewerNextChapter,LYRA_DEFAULT_ebookViewerPreviousChapter,LYRA_DEFAULT_ebookViewerRegionLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_next,LYRA_DEFAULT_open,LYRA_DEFAULT_previous,LYRA_DEFAULT_viewerSearchActiveMatch,LYRA_DEFAULT_viewerSearchMatchCount,LYRA_DEFAULT_viewerSearchNoMatches}from"../../../internal/default-strings.generated.js";const MAX_TOC_ITEMS=1e4;const MAX_TOC_DEPTH=100;const MAX_SEARCH_MATCHES=1e4;const TONE_FILL_TOKEN={accent:{token:"--lr-color-brand-quiet",fallback:"#ddf4ff"},success:{token:"--lr-color-success-quiet",fallback:"#dafbe1"},warning:{token:"--lr-color-warning-quiet",fallback:"#fff8c5"},danger:{token:"--lr-color-danger-quiet",fallback:"#ffebe9"},neutral:{token:"--lr-color-surface-raised",fallback:"#f6f8fa"}};const SEARCH_MATCH_FILL_TOKEN={token:"--lr-color-warning",fallback:"#9a6700"};class LyraEbookViewerBase extends LyraElement{}class LyraEbookViewer extends DocumentAnchorTarget(LyraEbookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.accessibleLabel="";this.location="";this.anchorKinds=["cfi","text-quote"];this.ebookState={kind:"idle"};this.searchMatches=[];this.searchActiveIndex=-1;this.mountRef=createRef();this.generation=0;this.searchQuery="";this.searchGeneration=0;this.anchorOperationGeneration=0;this.paintedHighlightCfis=[];this.announcements=new ViewerAnnouncementController(this);this.announcer=new Announcer({onFlush:text=>this.announcements.announcePolite(text)});this.previous=()=>{this.runRenditionNavigation("previous")};this.next=()=>{this.runRenditionNavigation("next")}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,ebookViewerLoadError:LYRA_DEFAULT_ebookViewerLoadError,ebookViewerNextChapter:LYRA_DEFAULT_ebookViewerNextChapter,ebookViewerPreviousChapter:LYRA_DEFAULT_ebookViewerPreviousChapter,ebookViewerRegionLabel:LYRA_DEFAULT_ebookViewerRegionLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,next:LYRA_DEFAULT_next,open:LYRA_DEFAULT_open,previous:LYRA_DEFAULT_previous,viewerSearchActiveMatch:LYRA_DEFAULT_viewerSearchActiveMatch,viewerSearchMatchCount:LYRA_DEFAULT_viewerSearchMatchCount,viewerSearchNoMatches:LYRA_DEFAULT_viewerSearchNoMatches}}static{this.styles=[LyraElement.styles,styles,srOnly]}updated(changed){super.updated(changed);this.announcements.transition("load",this.ebookState.kind,this.ebookState.kind==="error"?this.ebookState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});if(changed.has("location")){const fromRelocated=this.relocatedLocation===this.location;this.relocatedLocation=void 0;if(!fromRelocated&&this.rendition&&this.location)this.displayLocation(this.location)}if((changed.has("highlights")||changed.has("activeHighlightId"))&&this.rendition){this.repaintHighlights()}}connectedCallback(){super.connectedCallback();const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.connect();if(this.hasUpdated&&this.src.trim())this.scheduleAfterUpdate(()=>{void this.load()})}disconnectedCallback(){this.generation++;this.anchorOperationGeneration++;this.announcer.cancel();this.announcements.disconnect();this.teardown();this.ebookState={kind:"idle"};super.disconnectedCallback()}adoptedCallback(){const ownerWindow=this.ownerDocument.defaultView;if(ownerWindow)this.announcer.setTimerHost(ownerWindow);this.announcements.adopted()}teardown(){this.book?.destroy();this.book=void 0;this.rendition=void 0;this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchAnnotationCfi=void 0;this.paintedHighlightCfis=[]}async load(){const generation=++this.generation;const signal=this.beginAbortableLoad();this.teardown();if(!this.src.trim()){this.ebookState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){this.failWithLocalizedMessage(this.localize("documentPreviewUrlNotAllowed"));return}this.ebookState={kind:"loading"};let data;let factory;try{[data,factory]=await Promise.all([fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0).then(response=>{if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);return readResponseArrayBuffer(response)}),getEpubJs()]);if(!this.isConnected||generation!==this.generation)return;await assertEpubArchiveWithinLimits(data,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"ebookViewerLoadError")};this.emit("lr-render-error",{error});return}if(!factory){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}const mount=this.mountRef.value;if(!mount){this.failWithLocalizedMessage(this.localize("ebookViewerLoadError"));return}let candidateBook;try{const book=factory(data);candidateBook=book;const rendition=book.renderTo(mount,{width:"100%",height:"100%"});await book.ready;if(!this.isConnected||generation!==this.generation){book.destroy();return}await rendition.display(this.location||void 0);if(!this.isConnected||generation!==this.generation){book.destroy();return}rendition.on("relocated",loc=>{const cfi=loc?.start?.cfi??"";const href=loc?.start?.href??"";if(!cfi||cfi===this.location)return;this.relocatedLocation=cfi;this.location=cfi;this.emit("lr-location-change",{cfi,href})});rendition.on("selected",(cfiRange,contents)=>{const selection=contents?.window?.getSelection?.();const text=selection?String(selection.toString()):"";if(!text.trim())return;const rects=selection&&selection.rangeCount>0?Array.from(selection.getRangeAt(0).getClientRects()):[];this.emit("lr-text-select",{text,anchor:{kind:"cfi",cfi:cfiRange},rects})});this.book=book;this.rendition=rendition;candidateBook=void 0;this.ebookState={kind:"ready"};this.repaintHighlights()}catch(error){candidateBook?.destroy();if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}}failWithLocalizedMessage(message){const error=new LyraUserFacingError(message);this.ebookState={kind:"error",message};this.emit("lr-render-error",{error})}reportRenditionFailure(error,rendition,generation){if(!this.isConnected||generation!==this.generation||rendition!==this.rendition)return;this.ebookState={kind:"error",message:this.localize("ebookViewerLoadError")};this.emit("lr-render-error",{error})}displayLocation(location){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{void Promise.resolve(rendition.display(location)).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}runRenditionNavigation(action){const rendition=this.rendition;if(!rendition)return;const generation=this.generation;try{const task=action==="previous"?rendition.prev():rendition.next();void Promise.resolve(task).catch(error=>{this.reportRenditionFailure(error,rendition,generation)})}catch(error){this.reportRenditionFailure(error,rendition,generation)}}async getToc(){const book=this.book;if(!book)return[];await book.ready;if(this.book!==book)return[];const items=[];const seen=new WeakSet;const stack=(book.navigation?.toc??[]).map(entry=>({entry,level:1})).reverse();while(stack.length>0&&items.length<MAX_TOC_ITEMS){const current=stack.pop();const{entry,level}=current;if(!entry||typeof entry!=="object"||seen.has(entry))continue;seen.add(entry);items.push({id:entry.id||entry.href,label:String(entry.label??"").trim(),href:entry.href,level});if(level>=MAX_TOC_DEPTH||!Array.isArray(entry.subitems))continue;for(let index=entry.subitems.length-1;index>=0;index--){stack.push({entry:entry.subitems[index],level:level+1})}}return items}async scrollToAnchor(target){const operation=++this.anchorOperationGeneration;try{const performScrollToAnchor=Object.getPrototypeOf(LyraEbookViewer.prototype).performScrollToAnchor;return await performScrollToAnchor.call(this,target)}catch(error){if(operation!==this.anchorOperationGeneration)return false;const rendition=this.rendition;if(rendition)this.reportRenditionFailure(error,rendition,this.generation);this.emit("lr-anchor-result",{found:false});return false}}async applyAnchor(anchor){const rendition=this.rendition;const operation=this.anchorOperationGeneration;if(!rendition)return false;if(anchor.kind==="cfi"){if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(anchor.cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}if(anchor.kind==="text-quote"){const cfi=await this.findTextQuoteCfi(anchor.quote);if(!cfi)return false;if(operation!==this.anchorOperationGeneration||rendition!==this.rendition)return false;await rendition.display(cfi);return operation===this.anchorOperationGeneration&&rendition===this.rendition}return false}async findTextQuoteCfi(quote){const book=this.book;const generation=this.generation;if(!book)return null;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(!this.isConnected||generation!==this.generation||this.book!==book)return null;const results=await item.find(quote)??[];if(!this.isConnected||generation!==this.generation||this.book!==book)return null;if(results.length)return results[0].cfi}catch{continue}finally{if(loaded)item.unload()}}return null}repaintHighlights(){if(!this.rendition)return;for(const cfi of this.paintedHighlightCfis)this.rendition.annotations.remove(cfi,"highlight");this.paintedHighlightCfis=[];for(const highlight of this.highlights){if(highlight.anchor.kind!=="cfi")continue;const cfi=highlight.anchor.cfi;const tone=highlight.tone??"accent";this.rendition.annotations.highlight(cfi,{id:highlight.id},()=>this.emit("lr-highlight-activate",{id:highlight.id}),`lr-hl-${tone}`,this.resolveHighlightFill(TONE_FILL_TOKEN[tone]));this.paintedHighlightCfis.push(cfi)}}async search(query){const generation=++this.searchGeneration;this.searchQuery=query;this.clearSearchAnnotation();if(!this.book||!query.trim()){this.searchMatches=[];this.searchActiveIndex=-1;this.emitSearchChange();return 0}const matches=[];const book=this.book;const spineItems=book.spine?.spineItems??[];for(const item of spineItems){if(generation!==this.searchGeneration)return this.searchMatches.length;let loaded=false;try{await item.load(book.load?.bind(book));loaded=true;if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;const results=await item.find(query)??[];if(generation!==this.searchGeneration||this.book!==book)return this.searchMatches.length;for(const r of results){if(matches.length>=MAX_SEARCH_MATCHES)break;matches.push({cfi:r.cfi,excerpt:r.excerpt??""})}}catch{continue}finally{if(loaded)item.unload()}if(matches.length>=MAX_SEARCH_MATCHES)break}if(generation!==this.searchGeneration)return this.searchMatches.length;this.searchMatches=matches;this.searchActiveIndex=matches.length>0?0:-1;this.emitSearchChange();if(this.searchActiveIndex>=0)await this.showSearchMatch(this.searchActiveIndex,generation);return matches.length}async searchNext(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex+1)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}async searchPrevious(){if(!this.searchMatches.length)return false;const generation=++this.searchGeneration;this.searchActiveIndex=(this.searchActiveIndex-1+this.searchMatches.length)%this.searchMatches.length;this.emitSearchChange();return this.showSearchMatch(this.searchActiveIndex,generation)}clearSearch(){this.searchGeneration++;this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.clearSearchAnnotation();this.emit("lr-search-change",{query:"",matchCount:0,activeIndex:-1})}clearSearchAnnotation(){if(this.searchAnnotationCfi)this.rendition?.annotations.remove(this.searchAnnotationCfi,"highlight");this.searchAnnotationCfi=void 0}async showSearchMatch(index,generation=this.searchGeneration){const match=this.searchMatches[index];const rendition=this.rendition;if(!match||!rendition||generation!==this.searchGeneration)return false;this.clearSearchAnnotation();try{await rendition.display(match.cfi)}catch(error){if(generation===this.searchGeneration&&rendition===this.rendition){this.reportRenditionFailure(error,rendition,this.generation)}return false}if(generation!==this.searchGeneration||rendition!==this.rendition||this.searchMatches[index]!==match)return false;try{rendition.annotations.highlight(match.cfi,{},void 0,"lr-ebook-search",this.resolveHighlightFill(SEARCH_MATCH_FILL_TOKEN))}catch(error){this.reportRenditionFailure(error,rendition,this.generation);return false}this.searchAnnotationCfi=match.cfi;return true}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.searchActiveIndex});const numberFormat=getNumberFormat(this.effectiveLocale);announceSearchResult((key,fallback,values)=>this.localize(key,fallback,values?Object.fromEntries(Object.entries(values).map(([name,value])=>[name,typeof value==="number"?numberFormat.format(value):value])):void 0),this.announcer,this.searchMatches.length,this.searchActiveIndex)}resolveHighlightFill({token,fallback}){const value=this.ownerDocument.defaultView?.getComputedStyle(this).getPropertyValue(token).trim()??"";return{fill:value||fallback}}renderStatus(){if(this.ebookState.kind==="loading"){return html`<p class="status-note">${this.localize("loadingDocument")}</p>`}if(this.ebookState.kind==="error")return html`<div part="error">${this.ebookState.message}</div>`;if(this.ebookState.kind==="idle"){return html`<p class="status-note">${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}return nothing}render(){const disabled=this.ebookState.kind!=="ready";return html`
|
|
2
2
|
<div part="base" aria-busy=${this.ebookState.kind==="loading"?"true":"false"}>
|
|
3
3
|
<div part="toolbar">
|
|
4
4
|
<button part="previous-button" type="button" aria-label=${this.localize("ebookViewerPreviousChapter")} ?disabled=${disabled} @click=${this.previous}>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{unsafeSVG}from"lit/directives/unsafe-svg.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseText,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{finiteCount}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{createAnsiParser}from"../../../internal/ansi.js";import{loadNotebookSanitizer}from"./dompurify-loader.js";import{styles}from"./notebook-viewer.styles.js";import{sanitizeCssLength}from"../../../internal/safe-css.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_documentViewerMissingSanitizer,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_notebookViewerCodeCell,LYRA_DEFAULT_notebookViewerCollapseOutput,LYRA_DEFAULT_notebookViewerErrorOutput,LYRA_DEFAULT_notebookViewerInPrompt,LYRA_DEFAULT_notebookViewerInPromptEmpty,LYRA_DEFAULT_notebookViewerInvalid,LYRA_DEFAULT_notebookViewerLabel,LYRA_DEFAULT_notebookViewerMarkdownCell,LYRA_DEFAULT_notebookViewerRawCell,LYRA_DEFAULT_notebookViewerShowAllOutput,LYRA_DEFAULT_notebookViewerTooManyCells,LYRA_DEFAULT_notebookViewerUnrenderedOutput,LYRA_DEFAULT_notebookViewerUnsupportedVersion,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_CELLS=2e3;const MAX_OUTPUTS=2e4;const MAX_JSON_NODES=1e5;const SUPPORTED_MAJOR=4;const SUPPORTED_MINORS=[0,1,2,3,4,5];function joinSource(source){return Array.isArray(source)?source.join(""):source??""}function isDenseArray(value){for(let index=0;index<value.length;index++){if(!Object.prototype.hasOwnProperty.call(value,index))return false}return true}function joinText(text){if(typeof text==="string")return text;return Array.isArray(text)&&isDenseArray(text)&&text.every(item=>typeof item==="string")?text.join(""):""}function isTextValue(value){return typeof value==="string"||Array.isArray(value)&&isDenseArray(value)&&value.every(item=>typeof item==="string")}function isJsonValue(value){const pending=[value];let nodes=0;while(pending.length){const current=pending.pop();if(++nodes>MAX_JSON_NODES)return false;if(current===null||typeof current==="string"||typeof current==="boolean")continue;if(typeof current==="number"){if(!Number.isFinite(current))return false;continue}if(Array.isArray(current)){if(current.length>MAX_JSON_NODES-nodes-pending.length)return false;for(let index=current.length-1;index>=0;index--)pending.push(current[index]);continue}if(typeof current!=="object")return false;for(const key in current){if(!Object.prototype.hasOwnProperty.call(current,key))continue;if(pending.length>=MAX_JSON_NODES-nodes)return false;pending.push(current[key])}}return true}function isNotebookOutput(value){if(typeof value!=="object"||value===null)return false;const output=value;if(!["stream","error","display_data","execute_result"].includes(String(output["output_type"])))return false;if(output["text"]!==void 0&&!isTextValue(output["text"]))return false;if(output["traceback"]!==void 0&&!isTextValue(output["traceback"]))return false;if(output["ename"]!==void 0&&typeof output["ename"]!=="string")return false;if(output["evalue"]!==void 0&&typeof output["evalue"]!=="string")return false;if(output["name"]!==void 0&&output["name"]!=="stdout"&&output["name"]!=="stderr")return false;const data=output["data"];if(data===void 0)return true;if(typeof data!=="object"||data===null||Array.isArray(data))return false;const mimeData=data;for(const[mime,payload]of Object.entries(mimeData)){if(mime==="application/json"){if(typeof payload==="string"){try{if(!isJsonValue(JSON.parse(payload)))return false}catch{return false}}else if(!isJsonValue(payload))return false}else if(!isTextValue(payload)&&!isJsonValue(payload)){return false}}return true}function isNotebookShape(value){if(typeof value!=="object"||value===null)return false;const v=value;if(!Number.isInteger(v["nbformat"])||!Number.isInteger(v["nbformat_minor"])||!Array.isArray(v["cells"]))return false;const cells=v["cells"];let outputCount=0;for(let index=0;index<cells.length;index++){if(!Object.prototype.hasOwnProperty.call(cells,index))return false;const value2=cells[index];if(typeof value2!=="object"||value2===null)return false;const cell=value2;if(!["markdown","code","raw"].includes(String(cell["cell_type"])))return false;if(!isTextValue(cell["source"]))return false;if(cell["id"]!==void 0&&typeof cell["id"]!=="string")return false;if(cell["execution_count"]!==void 0&&cell["execution_count"]!==null&&(!Number.isInteger(cell["execution_count"])||cell["execution_count"]<0))return false;if(cell["outputs"]===void 0)continue;if(!Array.isArray(cell["outputs"]))return false;if(!isDenseArray(cell["outputs"]))return false;outputCount+=cell["outputs"].length;if(outputCount>MAX_OUTPUTS||!cell["outputs"].every(isNotebookOutput))return false}return true}class LyraNotebookViewerBase extends LyraElement{}class LyraNotebookViewer extends DocumentAnchorTarget(LyraNotebookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.outputCollapseLines=40;this.maxHeight="";this.anchorKinds=["node-path","fragment"];this.loadState={kind:"idle"};this.expandedOutputs=new Set;this.activeCellIndex=null;this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1;this.generation=0;this.sanitizerGeneration=0;this.sanitizerFailureReported=false;this.announcements=new ViewerAnnouncementController(this);this.sanitizedOutputCache=new Map;this.sanitizationTasks=new Map;this.renderCell=(cell,index)=>{const c=cell;const numberFormat=getNumberFormat(this.effectiveLocale);const inCount=c.execution_count==null?this.localize("notebookViewerInPromptEmpty"):this.localize("notebookViewerInPrompt",void 0,{count:numberFormat.format(c.execution_count)});const rowLabel=c.cell_type==="code"?this.localize("notebookViewerCodeCell",void 0,{index:numberFormat.format(index+1)}):c.cell_type==="markdown"?this.localize("notebookViewerMarkdownCell",void 0,{index:numberFormat.format(index+1)}):this.localize("notebookViewerRawCell",void 0,{index:numberFormat.format(index+1)});const active=this.activeCellIndex===index;const part=active?"cell cell-active":"cell";return html`<div part=${part} role="group" aria-label=${rowLabel} data-cell-type=${c.cell_type} ?data-active=${active}>
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import{unsafeSVG}from"lit/directives/unsafe-svg.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{specialistTokens}from"../../../internal/specialist-tokens.styles.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{isAbortError,isResourceLimitError,LyraUserFacingError,readResponseText,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{finiteCount}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{createAnsiParser}from"../../../internal/ansi.js";import{loadNotebookSanitizer}from"./dompurify-loader.js";import{styles}from"./notebook-viewer.styles.js";import{sanitizeCssColor,sanitizeCssLength}from"../../../internal/safe-css.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_documentViewerMissingSanitizer,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_notebookViewerCodeCell,LYRA_DEFAULT_notebookViewerCollapseOutput,LYRA_DEFAULT_notebookViewerErrorOutput,LYRA_DEFAULT_notebookViewerInPrompt,LYRA_DEFAULT_notebookViewerInPromptEmpty,LYRA_DEFAULT_notebookViewerInvalid,LYRA_DEFAULT_notebookViewerLabel,LYRA_DEFAULT_notebookViewerMarkdownCell,LYRA_DEFAULT_notebookViewerRawCell,LYRA_DEFAULT_notebookViewerShowAllOutput,LYRA_DEFAULT_notebookViewerTooManyCells,LYRA_DEFAULT_notebookViewerUnrenderedOutput,LYRA_DEFAULT_notebookViewerUnsupportedVersion,LYRA_DEFAULT_open}from"../../../internal/default-strings.generated.js";const MAX_CELLS=2e3;const MAX_OUTPUTS=2e4;const MAX_JSON_NODES=1e5;const SUPPORTED_MAJOR=4;const SUPPORTED_MINORS=[0,1,2,3,4,5];function joinSource(source){return Array.isArray(source)?source.join(""):source??""}function isDenseArray(value){for(let index=0;index<value.length;index++){if(!Object.prototype.hasOwnProperty.call(value,index))return false}return true}function joinText(text){if(typeof text==="string")return text;return Array.isArray(text)&&isDenseArray(text)&&text.every(item=>typeof item==="string")?text.join(""):""}function isTextValue(value){return typeof value==="string"||Array.isArray(value)&&isDenseArray(value)&&value.every(item=>typeof item==="string")}function isJsonValue(value){const pending=[value];let nodes=0;while(pending.length){const current=pending.pop();if(++nodes>MAX_JSON_NODES)return false;if(current===null||typeof current==="string"||typeof current==="boolean")continue;if(typeof current==="number"){if(!Number.isFinite(current))return false;continue}if(Array.isArray(current)){if(current.length>MAX_JSON_NODES-nodes-pending.length)return false;for(let index=current.length-1;index>=0;index--)pending.push(current[index]);continue}if(typeof current!=="object")return false;for(const key in current){if(!Object.prototype.hasOwnProperty.call(current,key))continue;if(pending.length>=MAX_JSON_NODES-nodes)return false;pending.push(current[key])}}return true}function isNotebookOutput(value){if(typeof value!=="object"||value===null)return false;const output=value;if(!["stream","error","display_data","execute_result"].includes(String(output["output_type"])))return false;if(output["text"]!==void 0&&!isTextValue(output["text"]))return false;if(output["traceback"]!==void 0&&!isTextValue(output["traceback"]))return false;if(output["ename"]!==void 0&&typeof output["ename"]!=="string")return false;if(output["evalue"]!==void 0&&typeof output["evalue"]!=="string")return false;if(output["name"]!==void 0&&output["name"]!=="stdout"&&output["name"]!=="stderr")return false;const data=output["data"];if(data===void 0)return true;if(typeof data!=="object"||data===null||Array.isArray(data))return false;const mimeData=data;for(const[mime,payload]of Object.entries(mimeData)){if(mime==="application/json"){if(typeof payload==="string"){try{if(!isJsonValue(JSON.parse(payload)))return false}catch{return false}}else if(!isJsonValue(payload))return false}else if(!isTextValue(payload)&&!isJsonValue(payload)){return false}}return true}function isNotebookShape(value){if(typeof value!=="object"||value===null)return false;const v=value;if(!Number.isInteger(v["nbformat"])||!Number.isInteger(v["nbformat_minor"])||!Array.isArray(v["cells"]))return false;const cells=v["cells"];let outputCount=0;for(let index=0;index<cells.length;index++){if(!Object.prototype.hasOwnProperty.call(cells,index))return false;const value2=cells[index];if(typeof value2!=="object"||value2===null)return false;const cell=value2;if(!["markdown","code","raw"].includes(String(cell["cell_type"])))return false;if(!isTextValue(cell["source"]))return false;if(cell["id"]!==void 0&&typeof cell["id"]!=="string")return false;if(cell["execution_count"]!==void 0&&cell["execution_count"]!==null&&(!Number.isInteger(cell["execution_count"])||cell["execution_count"]<0))return false;if(cell["outputs"]===void 0)continue;if(!Array.isArray(cell["outputs"]))return false;if(!isDenseArray(cell["outputs"]))return false;outputCount+=cell["outputs"].length;if(outputCount>MAX_OUTPUTS||!cell["outputs"].every(isNotebookOutput))return false}return true}class LyraNotebookViewerBase extends LyraElement{}class LyraNotebookViewer extends DocumentAnchorTarget(LyraNotebookViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.outputCollapseLines=40;this.maxHeight="";this.anchorKinds=["node-path","fragment"];this.loadState={kind:"idle"};this.expandedOutputs=new Set;this.activeCellIndex=null;this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1;this.generation=0;this.sanitizerGeneration=0;this.sanitizerFailureReported=false;this.announcements=new ViewerAnnouncementController(this);this.sanitizedOutputCache=new Map;this.sanitizationTasks=new Map;this.renderCell=(cell,index)=>{const c=cell;const numberFormat=getNumberFormat(this.effectiveLocale);const inCount=c.execution_count==null?this.localize("notebookViewerInPromptEmpty"):this.localize("notebookViewerInPrompt",void 0,{count:numberFormat.format(c.execution_count)});const rowLabel=c.cell_type==="code"?this.localize("notebookViewerCodeCell",void 0,{index:numberFormat.format(index+1)}):c.cell_type==="markdown"?this.localize("notebookViewerMarkdownCell",void 0,{index:numberFormat.format(index+1)}):this.localize("notebookViewerRawCell",void 0,{index:numberFormat.format(index+1)});const active=this.activeCellIndex===index;const part=active?"cell cell-active":"cell";return html`<div part=${part} role="group" aria-label=${rowLabel} data-cell-type=${c.cell_type} ?data-active=${active}>
|
|
2
2
|
<div part="cell-gutter">${c.cell_type==="code"?inCount:""}</div>
|
|
3
3
|
<div part="cell-source">
|
|
4
4
|
${c.cell_type==="markdown"?html`<lr-markdown .content=${joinSource(c.source)} escape-html sanitize></lr-markdown>`:c.cell_type==="code"?html`<lr-code-block .code=${joinSource(c.source)} language=${this.notebookLanguage()} line-numbers></lr-code-block>`:html`<pre part="raw-source" tabindex="0">${joinSource(c.source)}</pre>`}
|
|
5
5
|
${c.cell_type==="code"&&c.outputs?.length?html`<div part="outputs">${c.outputs.map((o,i)=>this.renderOutput(index,o,i))}</div>`:nothing}
|
|
6
6
|
</div>
|
|
7
|
-
</div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,notebookViewerCodeCell:LYRA_DEFAULT_notebookViewerCodeCell,notebookViewerCollapseOutput:LYRA_DEFAULT_notebookViewerCollapseOutput,notebookViewerErrorOutput:LYRA_DEFAULT_notebookViewerErrorOutput,notebookViewerInPrompt:LYRA_DEFAULT_notebookViewerInPrompt,notebookViewerInPromptEmpty:LYRA_DEFAULT_notebookViewerInPromptEmpty,notebookViewerInvalid:LYRA_DEFAULT_notebookViewerInvalid,notebookViewerLabel:LYRA_DEFAULT_notebookViewerLabel,notebookViewerMarkdownCell:LYRA_DEFAULT_notebookViewerMarkdownCell,notebookViewerRawCell:LYRA_DEFAULT_notebookViewerRawCell,notebookViewerShowAllOutput:LYRA_DEFAULT_notebookViewerShowAllOutput,notebookViewerTooManyCells:LYRA_DEFAULT_notebookViewerTooManyCells,notebookViewerUnrenderedOutput:LYRA_DEFAULT_notebookViewerUnrenderedOutput,notebookViewerUnsupportedVersion:LYRA_DEFAULT_notebookViewerUnsupportedVersion,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}get notebook(){return this._notebook}set notebook(value){const old=this._notebook;this._notebook=value;this.requestUpdate("notebook",old);this.parseInline()}get effectiveOutputCollapseLines(){return finiteCount(this.outputCollapseLines,40)}updated(changed){super.updated(changed);this.announcements.transition("load",this.loadState.kind,this.loadState.kind==="error"?this.loadState.message:this.localize("loadingDocument"));if(changed.has("src")&&!this._notebook)this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this._notebook===void 0){this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}if(this.hasUpdated&&this._notebook!==void 0&&this.loadState.kind==="loaded"){this.requestUpdate()}}disconnectedCallback(){this.generation++;this.sanitizerGeneration++;this.beginAbortableLoad();this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;if(this._notebook===void 0)this.loadState={kind:"idle"};this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}parseInline(){if(this._notebook===void 0)return;const generation=++this.generation;try{const raw=typeof this._notebook==="string"?JSON.parse(this._notebook):this._notebook;this.setDoc(raw,generation)}catch(error){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error})}}async loadFromSrc(){if(this._notebook!==void 0)return;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.loadState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.loadState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.loadState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const text=await readResponseText(response);if(!this.isConnected||generation!==this.generation)return;this.setDoc(JSON.parse(text),generation)}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.loadState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}setDoc(raw,generation){if(generation!==this.generation)return;if(!isNotebookShape(raw)){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error:new Error("invalid notebook shape")});return}if(raw.nbformat!==SUPPORTED_MAJOR||!SUPPORTED_MINORS.includes(raw.nbformat_minor)){this.loadState={kind:"error",message:this.localize("notebookViewerUnsupportedVersion",void 0,{version:`${raw.nbformat}.${raw.nbformat_minor}`})};this.emit("lr-render-error",{error:new Error("unsupported nbformat version")});return}if(raw.cells.length>MAX_CELLS){this.loadState={kind:"error",message:this.localize("notebookViewerTooManyCells")};this.emit("lr-render-error",{error:new Error("too many cells")});return}this.sanitizerGeneration++;this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;this.expandedOutputs=new Set;this.clearSearchState();this.loadState={kind:"loaded",doc:raw};const language=raw.metadata?.language_info?.name??raw.metadata?.kernelspec?.language??"";this.emit("lr-load",{cellCount:raw.cells.length,language})}async applyAnchor(anchor){if(this.loadState.kind!=="loaded")return false;const cells=this.loadState.doc.cells;let index=-1;if(anchor.kind==="node-path"&&Number.isInteger(anchor.path[0]))index=anchor.path[0];else if(anchor.kind==="fragment")index=cells.findIndex(c=>c.id===anchor.id);else return false;if(index<0||index>=cells.length)return false;this.activeCellIndex=index;return true}async search(query2){const q=query2.trim().toLocaleLowerCase(this.effectiveLocale);this.searchQuery=query2;if(this.loadState.kind!=="loaded"||!q){this.searchMatches=[]}else{this.searchMatches=this.loadState.doc.cells.reduce((acc,cell,i)=>{const source=joinSource(cell.source).toLocaleLowerCase(this.effectiveLocale);const outputText=(cell.outputs??[]).map(o=>joinText(o.text)+Object.values(o.data??{}).map(joinText).join("")).join(" ").toLocaleLowerCase(this.effectiveLocale);if(source.includes(q)||outputText.includes(q))acc.push(i);return acc},[])}this.activeSearchIndex=this.searchMatches.length?0:-1;this.activateSearchMatch();this.emitSearchChange();return this.searchMatches.length}async searchNext(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex+1)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}async searchPrevious(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex-1+this.searchMatches.length)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}clearSearch(){this.clearSearchState();this.emitSearchChange()}clearSearchState(){this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1}activateSearchMatch(){const index=this.searchMatches[this.activeSearchIndex];if(index===void 0)return;this.activeCellIndex=index;this.scheduleAfterUpdate(()=>{this.virtualListEl?.scrollToIndex(index,{align:"auto",behavior:"auto"})})}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.activeSearchIndex})}toggleOutput(index){const next=new Set(this.expandedOutputs);if(next.has(index))next.delete(index);else next.add(index);this.expandedOutputs=next}renderAnsiText(text){const segments=createAnsiParser().push(text);return html`${segments.map(seg=>html`<span style=${styleMap(this.segmentStyle(seg.styles))}>${seg.text}</span>`)}`}segmentStyle(s){const fg=s.fg??"var(--lr-color-text)";const bg=s.bg??"transparent";return{"font-weight":s.bold?"bold":"normal",opacity:s.dim?"0.7":"1","font-style":s.italic?"italic":"normal","text-decoration":s.underline?"underline":"none",color:s.inverse?bg:fg,"background-color":s.inverse?fg:bg}}renderTextOutput(index,text,tone){const lines=text.split("\n");const outputCollapseLines=this.effectiveOutputCollapseLines;const collapsible=outputCollapseLines>0&&lines.length>outputCollapseLines;const expanded=this.expandedOutputs.has(index)||!collapsible;const shown=expanded?text:lines.slice(0,outputCollapseLines).join("\n");const part=tone==="danger"?"output output-error":"output";return html`<div part=${part} data-output-type="stream" data-stream=${tone==="danger"?"stderr":"stdout"}
|
|
7
|
+
</div>`}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,documentViewerMissingSanitizer:LYRA_DEFAULT_documentViewerMissingSanitizer,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,notebookViewerCodeCell:LYRA_DEFAULT_notebookViewerCodeCell,notebookViewerCollapseOutput:LYRA_DEFAULT_notebookViewerCollapseOutput,notebookViewerErrorOutput:LYRA_DEFAULT_notebookViewerErrorOutput,notebookViewerInPrompt:LYRA_DEFAULT_notebookViewerInPrompt,notebookViewerInPromptEmpty:LYRA_DEFAULT_notebookViewerInPromptEmpty,notebookViewerInvalid:LYRA_DEFAULT_notebookViewerInvalid,notebookViewerLabel:LYRA_DEFAULT_notebookViewerLabel,notebookViewerMarkdownCell:LYRA_DEFAULT_notebookViewerMarkdownCell,notebookViewerRawCell:LYRA_DEFAULT_notebookViewerRawCell,notebookViewerShowAllOutput:LYRA_DEFAULT_notebookViewerShowAllOutput,notebookViewerTooManyCells:LYRA_DEFAULT_notebookViewerTooManyCells,notebookViewerUnrenderedOutput:LYRA_DEFAULT_notebookViewerUnrenderedOutput,notebookViewerUnsupportedVersion:LYRA_DEFAULT_notebookViewerUnsupportedVersion,open:LYRA_DEFAULT_open}}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}get notebook(){return this._notebook}set notebook(value){const old=this._notebook;this._notebook=value;this.requestUpdate("notebook",old);this.parseInline()}get effectiveOutputCollapseLines(){return finiteCount(this.outputCollapseLines,40)}updated(changed){super.updated(changed);this.announcements.transition("load",this.loadState.kind,this.loadState.kind==="error"?this.loadState.message:this.localize("loadingDocument"));if(changed.has("src")&&!this._notebook)this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this._notebook===void 0){this.scheduleAfterUpdate(()=>{void this.loadFromSrc()})}if(this.hasUpdated&&this._notebook!==void 0&&this.loadState.kind==="loaded"){this.requestUpdate()}}disconnectedCallback(){this.generation++;this.sanitizerGeneration++;this.beginAbortableLoad();this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;if(this._notebook===void 0)this.loadState={kind:"idle"};this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.announcements.adopted()}parseInline(){if(this._notebook===void 0)return;const generation=++this.generation;try{const raw=typeof this._notebook==="string"?JSON.parse(this._notebook):this._notebook;this.setDoc(raw,generation)}catch(error){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error})}}async loadFromSrc(){if(this._notebook!==void 0)return;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.loadState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.loadState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.loadState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const text=await readResponseText(response);if(!this.isConnected||generation!==this.generation)return;this.setDoc(JSON.parse(text),generation)}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.loadState={kind:"error",message:error instanceof LyraUserFacingError?error.message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}setDoc(raw,generation){if(generation!==this.generation)return;if(!isNotebookShape(raw)){this.loadState={kind:"error",message:this.localize("notebookViewerInvalid")};this.emit("lr-render-error",{error:new Error("invalid notebook shape")});return}if(raw.nbformat!==SUPPORTED_MAJOR||!SUPPORTED_MINORS.includes(raw.nbformat_minor)){this.loadState={kind:"error",message:this.localize("notebookViewerUnsupportedVersion",void 0,{version:`${raw.nbformat}.${raw.nbformat_minor}`})};this.emit("lr-render-error",{error:new Error("unsupported nbformat version")});return}if(raw.cells.length>MAX_CELLS){this.loadState={kind:"error",message:this.localize("notebookViewerTooManyCells")};this.emit("lr-render-error",{error:new Error("too many cells")});return}this.sanitizerGeneration++;this.sanitizedOutputCache.clear();this.sanitizationTasks.clear();this.sanitizerFailureReported=false;this.expandedOutputs=new Set;this.clearSearchState();this.loadState={kind:"loaded",doc:raw};const language=raw.metadata?.language_info?.name??raw.metadata?.kernelspec?.language??"";this.emit("lr-load",{cellCount:raw.cells.length,language})}async applyAnchor(anchor){if(this.loadState.kind!=="loaded")return false;const cells=this.loadState.doc.cells;let index=-1;if(anchor.kind==="node-path"&&Number.isInteger(anchor.path[0]))index=anchor.path[0];else if(anchor.kind==="fragment")index=cells.findIndex(c=>c.id===anchor.id);else return false;if(index<0||index>=cells.length)return false;this.activeCellIndex=index;return true}async search(query2){const q=query2.trim().toLocaleLowerCase(this.effectiveLocale);this.searchQuery=query2;if(this.loadState.kind!=="loaded"||!q){this.searchMatches=[]}else{this.searchMatches=this.loadState.doc.cells.reduce((acc,cell,i)=>{const source=joinSource(cell.source).toLocaleLowerCase(this.effectiveLocale);const outputText=(cell.outputs??[]).map(o=>joinText(o.text)+Object.values(o.data??{}).map(joinText).join("")).join(" ").toLocaleLowerCase(this.effectiveLocale);if(source.includes(q)||outputText.includes(q))acc.push(i);return acc},[])}this.activeSearchIndex=this.searchMatches.length?0:-1;this.activateSearchMatch();this.emitSearchChange();return this.searchMatches.length}async searchNext(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex+1)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}async searchPrevious(){if(!this.searchMatches.length)return false;this.activeSearchIndex=(this.activeSearchIndex-1+this.searchMatches.length)%this.searchMatches.length;this.activateSearchMatch();this.emitSearchChange();return true}clearSearch(){this.clearSearchState();this.emitSearchChange()}clearSearchState(){this.searchQuery="";this.searchMatches=[];this.activeSearchIndex=-1}activateSearchMatch(){const index=this.searchMatches[this.activeSearchIndex];if(index===void 0)return;this.activeCellIndex=index;this.scheduleAfterUpdate(()=>{this.virtualListEl?.scrollToIndex(index,{align:"auto",behavior:"auto"})})}emitSearchChange(){this.emit("lr-search-change",{query:this.searchQuery,matchCount:this.searchMatches.length,activeIndex:this.activeSearchIndex})}toggleOutput(index){const next=new Set(this.expandedOutputs);if(next.has(index))next.delete(index);else next.add(index);this.expandedOutputs=next}renderAnsiText(text){const segments=createAnsiParser().push(text);return html`${segments.map(seg=>html`<span style=${styleMap(this.segmentStyle(seg.styles))}>${seg.text}</span>`)}`}segmentStyle(s){const fg=sanitizeCssColor(s.fg)??"var(--lr-color-text)";const bg=sanitizeCssColor(s.bg)??"transparent";return{"font-weight":s.bold?"bold":"normal",opacity:s.dim?"0.7":"1","font-style":s.italic?"italic":"normal","text-decoration":s.underline?"underline":"none",color:s.inverse?bg:fg,"background-color":s.inverse?fg:bg}}renderTextOutput(index,text,tone){const lines=text.split("\n");const outputCollapseLines=this.effectiveOutputCollapseLines;const collapsible=outputCollapseLines>0&&lines.length>outputCollapseLines;const expanded=this.expandedOutputs.has(index)||!collapsible;const shown=expanded?text:lines.slice(0,outputCollapseLines).join("\n");const part=tone==="danger"?"output output-error":"output";return html`<div part=${part} data-output-type="stream" data-stream=${tone==="danger"?"stderr":"stdout"}
|
|
8
8
|
>${this.renderAnsiText(shown)}${collapsible?html`<button
|
|
9
9
|
part="output-toggle"
|
|
10
10
|
type="button"
|
|
@@ -27,6 +27,7 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
27
27
|
.keyFunction=${(item,i)=>item.id??i}
|
|
28
28
|
.activeId=${this.activeCellIndex??""}
|
|
29
29
|
@lr-visible-range-changed=${this.stopVirtualListEvent}
|
|
30
|
+
@lr-scroll=${this.stopVirtualListEvent}
|
|
30
31
|
></lr-virtual-list>`:this.loadState.kind==="loading"?html`<div part="spinner"><span class="sr-only">${this.localize("loadingDocument")}</span></div>`:this.loadState.kind==="error"?html`<div part="error">${this.loadState.message}</div>`:html`<p>${this.localize("documentPreviewEmpty",void 0,{type:this.localize("documentPreviewTypeDocument")})}</p>`}
|
|
31
32
|
${this.renderAnchorLiveRegion()}
|
|
32
33
|
</div>`}}__decorate([property()],LyraNotebookViewer.prototype,"src",void 0);__decorate([property({attribute:false})],LyraNotebookViewer.prototype,"notebook",null);__decorate([property()],LyraNotebookViewer.prototype,"name",void 0);__decorate([property({type:Number,attribute:"output-collapse-lines"})],LyraNotebookViewer.prototype,"outputCollapseLines",void 0);__decorate([property({attribute:"max-height"})],LyraNotebookViewer.prototype,"maxHeight",void 0);__decorate([state()],LyraNotebookViewer.prototype,"loadState",void 0);__decorate([state()],LyraNotebookViewer.prototype,"expandedOutputs",void 0);__decorate([state()],LyraNotebookViewer.prototype,"activeCellIndex",void 0);__decorate([state()],LyraNotebookViewer.prototype,"searchQuery",void 0);__decorate([state()],LyraNotebookViewer.prototype,"searchMatches",void 0);__decorate([state()],LyraNotebookViewer.prototype,"activeSearchIndex",void 0);__decorate([query("lr-virtual-list")],LyraNotebookViewer.prototype,"virtualListEl",void 0);export{LyraNotebookViewer};
|
|
@@ -30,6 +30,8 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
|
|
|
30
30
|
.keyFunction=${item=>item}
|
|
31
31
|
.activeId=${this.safePage}
|
|
32
32
|
@lr-visible-range-changed=${this.stopVirtualListEvent}
|
|
33
|
+
@lr-scroll=${this.stopVirtualListEvent}
|
|
34
|
+
@lr-load-more=${this.stopVirtualListEvent}
|
|
33
35
|
></lr-virtual-list>
|
|
34
36
|
</div>
|
|
35
37
|
`}}__decorate([property({attribute:false})],LyraPageRail.prototype,"viewer",void 0);__decorate([property()],LyraPageRail.prototype,"for",void 0);__decorate([property({type:Number,attribute:"page-count"})],LyraPageRail.prototype,"pageCount",void 0);__decorate([property({type:Number,reflect:true})],LyraPageRail.prototype,"page",void 0);__decorate([property({attribute:false})],LyraPageRail.prototype,"highlights",void 0);__decorate([property({type:Number,attribute:"thumb-width"})],LyraPageRail.prototype,"thumbWidth",void 0);__decorate([property()],LyraPageRail.prototype,"label",void 0);__decorate([state()],LyraPageRail.prototype,"resolvedPageCount",void 0);__decorate([state()],LyraPageRail.prototype,"thumbnailStates",void 0);__decorate([state()],LyraPageRail.prototype,"allocationWidth",void 0);export{LyraPageRail};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{assertTableDimensions,assertTableSize,isAbortError,isResourceLimitError,LyraResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{parseCellRange}from"../../../internal/cell-range.js";import{loadSheetJsCached}from"./spreadsheet-loader.js";import{styles}from"./spreadsheet-viewer.styles.js";import{assertXlsxArchiveWithinLimits}from"./xlsx-resource-guard.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_highlightWithLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_search,LYRA_DEFAULT_spreadsheetViewerLabel,LYRA_DEFAULT_spreadsheetViewerUnavailable}from"../../../internal/default-strings.generated.js";const MAX_SPREADSHEET_SHEETS=256;const MAX_SPREADSHEET_CELLS=1e6;const MAX_SEARCH_MATCHES=1e3;function columns(rows){return rows.reduce((max,row)=>Math.max(max,row.length),0)}function cell(value,locale){if(value===void 0||value===null)return"";return typeof value==="number"?getNumberFormat(locale).format(value):String(value)}class LyraSpreadsheetViewerBase extends LyraElement{}class LyraSpreadsheetViewer extends DocumentAnchorTarget(LyraSpreadsheetViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.anchorKinds=["cell-range"];this.fetchState={kind:"idle"};this.activeSheetIndex=0;this.activeRowKey="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchQuery="";this.lastSearchLocale="";this.generation=0;this.loadLibrary=loadSheetJsCached;this.lastLoadSrc="";this.announcements=new ViewerAnnouncementController(this);this.pendingAnimationFrames=new Set;this.onTabsChange=e=>{e.stopPropagation();const match=/^sheet-(\d+)$/.exec(e.detail.tabId);if(match)this.activeSheetIndex=Number(match[1])};this.stopInternalEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,highlightWithLabel:LYRA_DEFAULT_highlightWithLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,search:LYRA_DEFAULT_search,spreadsheetViewerLabel:LYRA_DEFAULT_spreadsheetViewerLabel,spreadsheetViewerUnavailable:LYRA_DEFAULT_spreadsheetViewerUnavailable}}static{this.styles=[LyraElement.styles,styles,srOnly]}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this.src===this.lastLoadSrc){this.scheduleAfterUpdate(()=>{void this.load()})}}disconnectedCallback(){this.generation++;this.cancelPendingAnimationFrames();this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.cancelPendingAnimationFrames();this.announcements.adopted()}waitForOwnerAnimationFrame(){const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return Promise.resolve(false);return new Promise(resolve=>{const pending={owner,resolve};this.pendingAnimationFrames.add(pending);pending.handle=owner.requestAnimationFrame(()=>{if(!this.pendingAnimationFrames.delete(pending))return;resolve(this.isConnected&&this.ownerDocument.defaultView===owner)})})}cancelPendingAnimationFrames(){const pendingFrames=[...this.pendingAnimationFrames];this.pendingAnimationFrames.clear();for(const pending of pendingFrames){if(pending.handle!==void 0)pending.owner.cancelAnimationFrame(pending.handle);pending.resolve(false)}}willUpdate(changed){super.willUpdate(changed);if(changed.has("src")){this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.activeRowKey="";this.activeSheetIndex=0}}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});const locale=this.effectiveLocale;if(locale!==this.lastSearchLocale){const shouldRecompute=!!this.searchQuery;this.lastSearchLocale=locale;if(shouldRecompute)this.scheduleAfterUpdate(()=>{void this.search(this.searchQuery)},"search")}}async load(){this.lastLoadSrc=this.src;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new LyraUserFacingError(this.localize("spreadsheetViewerUnavailable"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}const source=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;await assertXlsxArchiveWithinLimits(source,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return;const workbook=library.read(source,{type:"array"});if(!this.isConnected||generation!==this.generation)return;const sheetNames=workbook.SheetNames;if(sheetNames.length>MAX_SPREADSHEET_SHEETS){throw new LyraResourceLimitError("The spreadsheet contains too many sheets.")}const sheets=[];let totalRows=0;let maxColumns=0;let totalCells=0;for(const name of sheetNames){const rows=library.utils.sheet_to_json(workbook.Sheets[name],{header:1});assertTableSize(rows);totalRows+=rows.length;maxColumns=Math.max(maxColumns,columns(rows));totalCells+=rows.reduce((sum,row)=>sum+row.length,0);if(totalCells>MAX_SPREADSHEET_CELLS){throw new LyraResourceLimitError("The spreadsheet contains too many expanded cells.")}assertTableDimensions(totalRows,maxColumns);sheets.push({name,rows})}if(this.isConnected&&generation===this.generation){this.fetchState={kind:"loaded",sheets};if(this.searchQuery)await this.search(this.searchQuery)}}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}cellHighlightsForRow(rawRow,currentSheetName){const seen=new Set;return this.highlights.filter(highlight=>{if(seen.has(highlight.id))return false;seen.add(highlight.id);return true}).flatMap(highlight=>{if(highlight.anchor.kind!=="cell-range")return[];const parsed=parseCellRange(highlight.anchor.range);if(!parsed)return[];const sheetName=highlight.anchor.sheet??parsed.sheet;if(sheetName!==void 0&&sheetName!==currentSheetName)return[];return rawRow-1>=parsed.startRow&&rawRow-1<=parsed.endRow?[{highlight,parsed}]:[]})}renderCell(value,colIndex,rowHighlights,role){const text=cell(value,this.effectiveLocale);const colHighlights=rowHighlights.filter(entry=>colIndex>=entry.parsed.startCol&&colIndex<=entry.parsed.endCol);if(!colHighlights.length)return html`<div part="cell" role=${role}>${text}</div>`;const active=colHighlights.find(entry=>entry.highlight.id===this.activeHighlightId);const primary=active??colHighlights[0];const accessibleLabel=this.localize("highlightWithLabel",void 0,{label:primary.highlight.label?`${text} \u2014 ${primary.highlight.label}`:text});const activate=()=>{this.emit("lr-highlight-activate",{id:primary.highlight.id})};return html`<div
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{assertTableDimensions,assertTableSize,isAbortError,isResourceLimitError,LyraResourceLimitError,LyraUserFacingError,readResponseArrayBuffer,resolveOwnerFetchTarget}from"../../../internal/resource-loader.js";import{srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{DocumentAnchorTarget}from"../../../internal/anchor-target.js";import{parseCellRange}from"../../../internal/cell-range.js";import{loadSheetJsCached}from"./spreadsheet-loader.js";import{styles}from"./spreadsheet-viewer.styles.js";import{assertXlsxArchiveWithinLimits}from"./xlsx-resource-guard.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{ViewerAnnouncementController}from"../viewer-announcements.js";import{LYRA_DEFAULT_anchorJumped,LYRA_DEFAULT_anchorJumpedToPage,LYRA_DEFAULT_anchorNotFound,LYRA_DEFAULT_collapse,LYRA_DEFAULT_details,LYRA_DEFAULT_documentPreviewEmpty,LYRA_DEFAULT_documentPreviewFailedToLoad,LYRA_DEFAULT_documentPreviewResourceTooLarge,LYRA_DEFAULT_documentPreviewTypeDocument,LYRA_DEFAULT_documentPreviewUrlNotAllowed,LYRA_DEFAULT_highlightWithLabel,LYRA_DEFAULT_loading,LYRA_DEFAULT_loadingDocument,LYRA_DEFAULT_noData,LYRA_DEFAULT_open,LYRA_DEFAULT_search,LYRA_DEFAULT_spreadsheetViewerLabel,LYRA_DEFAULT_spreadsheetViewerUnavailable}from"../../../internal/default-strings.generated.js";const MAX_SPREADSHEET_SHEETS=256;const MAX_SPREADSHEET_CELLS=1e6;const MAX_SEARCH_MATCHES=1e3;function columns(rows){return rows.reduce((max,row)=>Math.max(max,row.length),0)}function cell(value,locale){if(value===void 0||value===null)return"";return typeof value==="number"?getNumberFormat(locale).format(value):String(value)}class LyraSpreadsheetViewerBase extends LyraElement{}class LyraSpreadsheetViewer extends DocumentAnchorTarget(LyraSpreadsheetViewerBase){constructor(){super(...arguments);this.src="";this.name="";this.anchorKinds=["cell-range"];this.fetchState={kind:"idle"};this.activeSheetIndex=0;this.activeRowKey="";this.searchMatches=[];this.searchActiveIndex=-1;this.searchQuery="";this.lastSearchLocale="";this.generation=0;this.loadLibrary=loadSheetJsCached;this.lastLoadSrc="";this.announcements=new ViewerAnnouncementController(this);this.pendingAnimationFrames=new Set;this.onTabsChange=e=>{e.stopPropagation();const match=/^sheet-(\d+)$/.exec(e.detail.tabId);if(match)this.activeSheetIndex=Number(match[1])};this.stopInternalEvent=event=>{event.stopPropagation()}}static{this.defaultStrings={...super.defaultStrings,anchorJumped:LYRA_DEFAULT_anchorJumped,anchorJumpedToPage:LYRA_DEFAULT_anchorJumpedToPage,anchorNotFound:LYRA_DEFAULT_anchorNotFound,collapse:LYRA_DEFAULT_collapse,details:LYRA_DEFAULT_details,documentPreviewEmpty:LYRA_DEFAULT_documentPreviewEmpty,documentPreviewFailedToLoad:LYRA_DEFAULT_documentPreviewFailedToLoad,documentPreviewResourceTooLarge:LYRA_DEFAULT_documentPreviewResourceTooLarge,documentPreviewTypeDocument:LYRA_DEFAULT_documentPreviewTypeDocument,documentPreviewUrlNotAllowed:LYRA_DEFAULT_documentPreviewUrlNotAllowed,highlightWithLabel:LYRA_DEFAULT_highlightWithLabel,loading:LYRA_DEFAULT_loading,loadingDocument:LYRA_DEFAULT_loadingDocument,noData:LYRA_DEFAULT_noData,open:LYRA_DEFAULT_open,search:LYRA_DEFAULT_search,spreadsheetViewerLabel:LYRA_DEFAULT_spreadsheetViewerLabel,spreadsheetViewerUnavailable:LYRA_DEFAULT_spreadsheetViewerUnavailable}}static{this.styles=[LyraElement.styles,styles,srOnly]}connectedCallback(){super.connectedCallback();this.announcements.connect();if(this.hasUpdated&&this.src&&this.src===this.lastLoadSrc){this.scheduleAfterUpdate(()=>{void this.load()})}}disconnectedCallback(){this.generation++;this.cancelPendingAnimationFrames();this.announcements.disconnect();super.disconnectedCallback()}adoptedCallback(){this.cancelPendingAnimationFrames();this.announcements.adopted()}waitForOwnerAnimationFrame(){const owner=this.ownerDocument.defaultView;if(!owner||!this.isConnected)return Promise.resolve(false);return new Promise(resolve=>{const pending={owner,resolve};this.pendingAnimationFrames.add(pending);pending.handle=owner.requestAnimationFrame(()=>{if(!this.pendingAnimationFrames.delete(pending))return;resolve(this.isConnected&&this.ownerDocument.defaultView===owner)})})}cancelPendingAnimationFrames(){const pendingFrames=[...this.pendingAnimationFrames];this.pendingAnimationFrames.clear();for(const pending of pendingFrames){if(pending.handle!==void 0)pending.owner.cancelAnimationFrame(pending.handle);pending.resolve(false)}}willUpdate(changed){super.willUpdate(changed);if(changed.has("src")){this.searchQuery="";this.searchMatches=[];this.searchActiveIndex=-1;this.activeRowKey="";this.activeSheetIndex=0}}updated(changed){super.updated(changed);this.announcements.transition("load",this.fetchState.kind,this.fetchState.kind==="error"?this.fetchState.message:this.localize("loadingDocument"));if(changed.has("src"))this.scheduleAfterUpdate(()=>{void this.load()});const locale=this.effectiveLocale;if(locale!==this.lastSearchLocale){const shouldRecompute=!!this.searchQuery;this.lastSearchLocale=locale;if(shouldRecompute)this.scheduleAfterUpdate(()=>{void this.search(this.searchQuery)},"search")}}async load(){this.lastLoadSrc=this.src;const generation=++this.generation;const signal=this.beginAbortableLoad();if(!this.src){this.fetchState={kind:"idle"};return}const fetchTarget=resolveOwnerFetchTarget(this,this.src);if(!fetchTarget){const error=new LyraUserFacingError(this.localize("documentPreviewUrlNotAllowed"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}this.fetchState={kind:"loading"};try{const response=await fetchTarget.view.fetch(fetchTarget.url,signal?{signal}:void 0);if(!this.isConnected||generation!==this.generation)return;if(!response.ok)throw new Error(`${response.status} ${response.statusText}`);const library=await this.loadLibrary();if(!this.isConnected||generation!==this.generation)return;if(!library){const error=new LyraUserFacingError(this.localize("spreadsheetViewerUnavailable"));this.fetchState={kind:"error",message:error.message};this.emit("lr-render-error",{error});return}const source=await readResponseArrayBuffer(response);if(!this.isConnected||generation!==this.generation)return;await assertXlsxArchiveWithinLimits(source,void 0,void 0,{signal});if(!this.isConnected||generation!==this.generation)return;const workbook=library.read(source,{type:"array"});if(!this.isConnected||generation!==this.generation)return;const sheetNames=workbook.SheetNames;if(!Array.isArray(sheetNames)||!sheetNames.every(name=>typeof name==="string")){throw new Error("The xlsx peer returned a malformed workbook.")}if(sheetNames.length>MAX_SPREADSHEET_SHEETS){throw new LyraResourceLimitError("The spreadsheet contains too many sheets.")}const sheets=[];let totalRows=0;let maxColumns=0;let totalCells=0;for(const name of sheetNames){const rows=library.utils.sheet_to_json(workbook.Sheets[name],{header:1});assertTableSize(rows);totalRows+=rows.length;maxColumns=Math.max(maxColumns,columns(rows));totalCells+=rows.reduce((sum,row)=>sum+row.length,0);if(totalCells>MAX_SPREADSHEET_CELLS){throw new LyraResourceLimitError("The spreadsheet contains too many expanded cells.")}assertTableDimensions(totalRows,maxColumns);sheets.push({name,rows})}if(this.isConnected&&generation===this.generation){this.fetchState={kind:"loaded",sheets};if(this.searchQuery)await this.search(this.searchQuery)}}catch(error){if(isAbortError(error)||!this.isConnected||generation!==this.generation)return;this.fetchState={kind:"error",message:this.localize(isResourceLimitError(error)?"documentPreviewResourceTooLarge":"documentPreviewFailedToLoad")};this.emit("lr-render-error",{error})}}cellHighlightsForRow(rawRow,currentSheetName){const seen=new Set;return this.highlights.filter(highlight=>{if(seen.has(highlight.id))return false;seen.add(highlight.id);return true}).flatMap(highlight=>{if(highlight.anchor.kind!=="cell-range")return[];const parsed=parseCellRange(highlight.anchor.range);if(!parsed)return[];const sheetName=highlight.anchor.sheet??parsed.sheet;if(sheetName!==void 0&&sheetName!==currentSheetName)return[];return rawRow-1>=parsed.startRow&&rawRow-1<=parsed.endRow?[{highlight,parsed}]:[]})}renderCell(value,colIndex,rowHighlights,role){const text=cell(value,this.effectiveLocale);const colHighlights=rowHighlights.filter(entry=>colIndex>=entry.parsed.startCol&&colIndex<=entry.parsed.endCol);if(!colHighlights.length)return html`<div part="cell" role=${role}>${text}</div>`;const active=colHighlights.find(entry=>entry.highlight.id===this.activeHighlightId);const primary=active??colHighlights[0];const accessibleLabel=this.localize("highlightWithLabel",void 0,{label:primary.highlight.label?`${text} \u2014 ${primary.highlight.label}`:text});const activate=()=>{this.emit("lr-highlight-activate",{id:primary.highlight.id})};return html`<div
|
|
2
2
|
part="cell cell-highlight"
|
|
3
3
|
role=${role}
|
|
4
4
|
?data-active=${!!active}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html}from"lit";import{property,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"./announcer.js";import{isAccessibilityVisible}from"./accessibility-visibility.js";import{LyraElement}from"./lyra-element.js";import{normalizeQuoteText,scopeFromElement,buildQuoteAnchor}from"./text-quote.js";const ANCHOR_RETRY_INTERVAL_MS=250;const ANCHOR_TIMEOUT_MS=5e3;function selectionRange(root){const document=root.ownerDocument;const view=document.defaultView;const renderRoot=root.renderRoot;const shadowRoot=renderRoot?.nodeType===11&&renderRoot.host===root?renderRoot:void 0;const globalSelection=view?.getSelection()??null;if(globalSelection?.getComposedRanges&&shadowRoot){const[composed]=globalSelection.getComposedRanges({shadowRoots:[shadowRoot]});if(!composed)return null;if(composed.startContainer===composed.endContainer&&composed.startOffset===composed.endOffset)return null;const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}const shadowSelection=shadowRoot?.getSelection?.();const selection=shadowSelection??globalSelection;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}function DocumentAnchorTarget(Base){class DocumentAnchorTargetElement extends Base{constructor(){super(...arguments);this.highlights=[];this.activeHighlightId=null;this.anchor=null;this.anchorKinds=[];this.anchorRetryIntervalMs=ANCHOR_RETRY_INTERVAL_MS;this.anchorTimeoutMs=ANCHOR_TIMEOUT_MS;this.anchorAnnouncementText="";this.anchorGeneration=0}connectedCallback(){super.connectedCallback();this.anchorAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}willUpdate(changed){super.willUpdate(changed);if(changed.has("anchor")&&this.anchor!==null){void this.scrollToAnchor(this.anchor).catch(()=>void 0)}}disconnectedCallback(){this.anchorGeneration++;this.cancelAnchorRetry();this.unbindTextSelection();this.anchorAnnouncementSink?.release();this.anchorAnnouncementSink=void 0;super.disconnectedCallback()}async applyAnchor(_anchor){return false}computeSelectionAnchor(range,_text){const scope=scopeFromElement(this.renderRoot);return buildQuoteAnchor(range,scope)}cancelAnchorRetry(){if(this.anchorRetryHandle!==void 0){this.anchorRetryOwner?.clearTimeout(this.anchorRetryHandle);this.anchorRetryHandle=void 0}this.anchorRetryOwner=void 0;const resolveWait=this.anchorRetryResolve;if(resolveWait){this.anchorRetryResolve=void 0;resolveWait()}}async scrollToAnchor(target){const generation=++this.anchorGeneration;this.cancelAnchorRetry();await this.updateComplete;if(generation!==this.anchorGeneration)return false;const highlightId=typeof target==="string"?target:void 0;const anchor=typeof target==="string"?this.highlights.find(h=>h.id===target)?.anchor:target;if(!anchor){this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}const ok=await this.resolveWithRetry(anchor,generation);if(generation!==this.anchorGeneration)return false;if(ok&&highlightId)this.activeHighlightId=highlightId;this.announceAnchorResult(anchor,ok);this.emit("lr-anchor-result",{found:ok});return ok}async resolveWithRetry(anchor,generation){const deadline=Date.now()+this.anchorTimeoutMs;for(;;){if(generation!==this.anchorGeneration)return false;const ok=await this.applyAnchor(anchor);if(generation!==this.anchorGeneration)return false;if(ok)return true;if(Date.now()>=deadline)return false;const view=this.ownerDocument.defaultView;if(!view)return false;await new Promise(resolve=>{this.anchorRetryResolve=resolve;this.anchorRetryOwner=view;let handle;handle=view.setTimeout(()=>{if(this.anchorRetryHandle===handle&&this.anchorRetryOwner===view){this.anchorRetryHandle=void 0;this.anchorRetryOwner=void 0}if(this.anchorRetryResolve===resolve)this.anchorRetryResolve=void 0;resolve()},this.anchorRetryIntervalMs);this.anchorRetryHandle=handle})}}announceAnchorResult(anchor,found){if(!found||!anchor){this.announce(this.localize("anchorNotFound"));return}const page="page"in anchor?anchor.page:void 0;this.announce(page!=null?this.localize("anchorJumpedToPage",void 0,{page}):this.localize("anchorJumped"))}announce(text){if(isAccessibilityVisible(this))this.anchorAnnouncementSink?.announce(text);this.anchorAnnouncementText=text}renderAnchorLiveRegion(){return html`<div
|
|
1
|
+
var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)if(d=decorators[i])r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r;return c>3&&r&&Object.defineProperty(target,key,r),r};import{html}from"lit";import{property,state}from"lit/decorators.js";import{acquireAnnouncementSink}from"./announcer.js";import{isAccessibilityVisible}from"./accessibility-visibility.js";import{LyraElement}from"./lyra-element.js";import{normalizeQuoteText,scopeFromElement,buildQuoteAnchor}from"./text-quote.js";const ANCHOR_RETRY_INTERVAL_MS=250;const ANCHOR_TIMEOUT_MS=5e3;function selectionRange(root){const document=root.ownerDocument;const view=document.defaultView;const renderRoot=root.renderRoot;const shadowRoot=renderRoot?.nodeType===11&&renderRoot.host===root?renderRoot:void 0;const globalSelection=view?.getSelection()??null;if(globalSelection?.getComposedRanges&&shadowRoot){const[composed]=globalSelection.getComposedRanges({shadowRoots:[shadowRoot]});if(!composed)return null;if(composed.startContainer===composed.endContainer&&composed.startOffset===composed.endOffset)return null;const range=document.createRange();range.setStart(composed.startContainer,composed.startOffset);range.setEnd(composed.endContainer,composed.endOffset);return range}const shadowSelection=shadowRoot?.getSelection?.();const selection=shadowSelection??globalSelection;if(!selection||selection.rangeCount===0||selection.isCollapsed)return null;return selection.getRangeAt(0)}function DocumentAnchorTarget(Base){class DocumentAnchorTargetElement extends Base{constructor(){super(...arguments);this.highlights=[];this.activeHighlightId=null;this.anchor=null;this.anchorKinds=[];this.anchorRetryIntervalMs=ANCHOR_RETRY_INTERVAL_MS;this.anchorTimeoutMs=ANCHOR_TIMEOUT_MS;this.anchorAnnouncementText="";this.anchorGeneration=0}connectedCallback(){super.connectedCallback();this.anchorAnnouncementSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this})}willUpdate(changed){super.willUpdate(changed);if(changed.has("anchor")&&this.anchor!==null){void this.scrollToAnchor(this.anchor).catch(()=>void 0)}}disconnectedCallback(){this.anchorGeneration++;this.cancelAnchorRetry();this.unbindTextSelection();this.anchorAnnouncementSink?.release();this.anchorAnnouncementSink=void 0;super.disconnectedCallback()}async applyAnchor(_anchor){return false}computeSelectionAnchor(range,_text){const scope=scopeFromElement(this.renderRoot);return buildQuoteAnchor(range,scope)}cancelAnchorRetry(){if(this.anchorRetryHandle!==void 0){this.anchorRetryOwner?.clearTimeout(this.anchorRetryHandle);this.anchorRetryHandle=void 0}this.anchorRetryOwner=void 0;const resolveWait=this.anchorRetryResolve;if(resolveWait){this.anchorRetryResolve=void 0;resolveWait()}}async scrollToAnchor(target){const generation=++this.anchorGeneration;try{return await this.performScrollToAnchor(target,generation)}catch{if(generation!==this.anchorGeneration)return false;this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}}async performScrollToAnchor(target,generation=++this.anchorGeneration){this.cancelAnchorRetry();await this.updateComplete;if(generation!==this.anchorGeneration)return false;const highlightId=typeof target==="string"?target:void 0;const anchor=typeof target==="string"?this.highlights.find(h=>h.id===target)?.anchor:target;if(!anchor){this.announceAnchorResult(void 0,false);this.emit("lr-anchor-result",{found:false});return false}const ok=await this.resolveWithRetry(anchor,generation);if(generation!==this.anchorGeneration)return false;if(ok&&highlightId)this.activeHighlightId=highlightId;this.announceAnchorResult(anchor,ok);this.emit("lr-anchor-result",{found:ok});return ok}async resolveWithRetry(anchor,generation){const deadline=Date.now()+this.anchorTimeoutMs;for(;;){if(generation!==this.anchorGeneration)return false;const ok=await this.applyAnchor(anchor);if(generation!==this.anchorGeneration)return false;if(ok)return true;if(Date.now()>=deadline)return false;const view=this.ownerDocument.defaultView;if(!view)return false;await new Promise(resolve=>{this.anchorRetryResolve=resolve;this.anchorRetryOwner=view;let handle;handle=view.setTimeout(()=>{if(this.anchorRetryHandle===handle&&this.anchorRetryOwner===view){this.anchorRetryHandle=void 0;this.anchorRetryOwner=void 0}if(this.anchorRetryResolve===resolve)this.anchorRetryResolve=void 0;resolve()},this.anchorRetryIntervalMs);this.anchorRetryHandle=handle})}}announceAnchorResult(anchor,found){if(!found||!anchor){this.announce(this.localize("anchorNotFound"));return}const page="page"in anchor?anchor.page:void 0;this.announce(page!=null?this.localize("anchorJumpedToPage",void 0,{page}):this.localize("anchorJumped"))}announce(text){if(isAccessibilityVisible(this))this.anchorAnnouncementSink?.announce(text);this.anchorAnnouncementText=text}renderAnchorLiveRegion(){return html`<div
|
|
2
2
|
part="anchor-live-region"
|
|
3
3
|
class="sr-only"
|
|
4
4
|
aria-hidden="true"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.
|
|
1
|
+
const LYRA_PACKAGE_NAME="@aceshooting/lyra-ui";const LYRA_PACKAGE_VERSION="8.1.0";export{LYRA_PACKAGE_NAME,LYRA_PACKAGE_VERSION};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rejects an attribute name that should never survive a raw DOM clone of consumer-supplied SVG
|
|
3
|
+
* content (`<lr-icon>`'s and `<lr-icon-button>`'s slotted custom-content path -- unlike a fetched
|
|
4
|
+
* `src` document, which is sanitized through DOMPurify before it ever reaches the DOM, a slotted
|
|
5
|
+
* clone has no sanitizer in the loop, so this predicate is that path's own trust boundary).
|
|
6
|
+
* Event-handler content attributes (`on*`) execute as inline JS once connected; `href`/
|
|
7
|
+
* `xlink:href` on an SVG `<a>`/`<use>`/`<image>` can carry a `javascript:` URI or reference an
|
|
8
|
+
* external resource. Every other presentational attribute (`d`, `fill`, `stroke`, `viewBox`,
|
|
9
|
+
* `transform`, gradient stops, …) is left untouched -- this is a denylist, not an allowlist,
|
|
10
|
+
* because SVG's legitimate presentation-attribute vocabulary is too large to enumerate without
|
|
11
|
+
* silently breaking real icon markup.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isUnsafeSvgCloneAttribute(name: string): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function isUnsafeSvgCloneAttribute(name){const lower=name.toLowerCase();return lower.startsWith("on")||lower==="href"||lower==="xlink:href"}export{isUnsafeSvgCloneAttribute};
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
* as a no-op -- `AnchoredValidityController` (the shared validity-refresh controller every
|
|
11
11
|
* form-associated component uses) calls `internals.setValidity()` on every update, which would
|
|
12
12
|
* otherwise throw the moment any of those components' `value` changes, not just at construction.
|
|
13
|
+
* `states` is a real `Set` -- several controls (e.g. `lr-input`) call
|
|
14
|
+
* `internals.states.add('blank')`/`.delete('blank')` on every update to drive a custom-state
|
|
15
|
+
* pseudo-class, which would otherwise throw on `add` of `undefined`.
|
|
13
16
|
*
|
|
14
17
|
* `attachInternals()` is specified on the `HTMLElement` interface (not `Element`), and every
|
|
15
18
|
* `lr-*` component is an `HTMLElement` subclass (via `LitElement`), so this patches
|
|
@@ -29,6 +32,7 @@ interface StubValidityState {
|
|
|
29
32
|
interface StubElementInternals {
|
|
30
33
|
form: HTMLFormElement | null;
|
|
31
34
|
labels: NodeList;
|
|
35
|
+
states: Set<string>;
|
|
32
36
|
validity: StubValidityState;
|
|
33
37
|
validationMessage: string;
|
|
34
38
|
willValidate: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function createStubInternals(){return{form:null,labels:document.createDocumentFragment().querySelectorAll("label"),validity:{valid:true},validationMessage:"",willValidate:true,setFormValue(){},checkValidity(){return true},reportValidity(){return true},setValidity(){}}}function installHappyDomFormAssociatedShims(){if(typeof HTMLElement==="undefined")return;if(typeof HTMLElement.prototype.attachInternals==="function")return;HTMLElement.prototype.attachInternals=function attachInternals(){return createStubInternals()}}function installStubInternalsForTest(_host){return createStubInternals()}export{installHappyDomFormAssociatedShims,installStubInternalsForTest};
|
|
1
|
+
function createStubInternals(){return{form:null,labels:document.createDocumentFragment().querySelectorAll("label"),states:new Set,validity:{valid:true},validationMessage:"",willValidate:true,setFormValue(){},checkValidity(){return true},reportValidity(){return true},setValidity(){}}}function installHappyDomFormAssociatedShims(){if(typeof HTMLElement==="undefined")return;if(typeof HTMLElement.prototype.attachInternals==="function")return;HTMLElement.prototype.attachInternals=function attachInternals(){return createStubInternals()}}function installStubInternalsForTest(_host){return createStubInternals()}export{installHappyDomFormAssociatedShims,installStubInternalsForTest};
|
|
@@ -17,18 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
A compact chip representing one file queued for (or already part of) a chat message — used in a
|
|
19
19
|
composer's pre-send attachment tray or a sent message's attachments display. Two independent ways
|
|
20
|
-
to populate it: set `file` to a real `File` (fresh from a picker/drop), from which `name`/`
|
|
21
|
-
`mime-type` and the image thumbnail are all auto-derived; or set the plain `name`/`
|
|
20
|
+
to populate it: set `file` to a real `File` (fresh from a picker/drop), from which `name`/`bytes`/
|
|
21
|
+
`mime-type` and the image thumbnail are all auto-derived; or set the plain `name`/`bytes`/
|
|
22
22
|
`mime-type`/`thumbnail-src` props instead, for reconstructing a chip from server-persisted
|
|
23
23
|
attachment metadata after a page reload, when no real `File` object exists any more. `file` always
|
|
24
24
|
wins when both are present. When a real `File` or `preview-src` is available, the chip also offers
|
|
25
25
|
a localized preview action that opens `<lr-document-viewer>` using the same effective MIME type.
|
|
26
26
|
|
|
27
27
|
**Properties:**
|
|
28
|
-
- `file?: File` (attribute `false`, i.e. property-only) — when set, `name`/`
|
|
28
|
+
- `file?: File` (attribute `false`, i.e. property-only) — when set, `name`/`bytes`/`mimeType`/the
|
|
29
29
|
image thumbnail are all derived from it, taking precedence over the independent props below
|
|
30
30
|
- `name: string = ''` — filename, used only while `file` is unset
|
|
31
|
-
- `
|
|
31
|
+
- `bytes: number = 0` — file size in bytes, used only while `file` is unset
|
|
32
32
|
- `mimeType: string = ''` (attribute `mime-type`) — used only while `file` is unset
|
|
33
33
|
- `thumbnailSrc: string = ''` (attribute `thumbnail-src`) — thumbnail image URL, used only while
|
|
34
34
|
`file` is unset; rendered whenever present regardless of `mimeType` (no `file`-derived equivalent
|
|
@@ -61,6 +61,12 @@ a localized preview action that opens `<lr-document-viewer>` using the same effe
|
|
|
61
61
|
- `untitledLabel: string = 'Untitled file'` (attribute `untitled-label`) — fallback filename and
|
|
62
62
|
tooltip when neither `file` nor `name` supplies a name
|
|
63
63
|
|
|
64
|
+
**Renamed in 8.0.0 — breaking:** the byte count is `bytes`, not `size` (same rename as
|
|
65
|
+
`lr-file-icon`'s). Everywhere else in this library `size` names a tier on the shared size ladder,
|
|
66
|
+
and a numeric byte count answering to the same property name is a collision a consumer only
|
|
67
|
+
discovers at runtime. A leftover `size="245000"` is an unknown attribute now: `bytes` stays `0` and
|
|
68
|
+
the `size` part renders nothing.
|
|
69
|
+
|
|
64
70
|
The component identifies *which* attachment a `lr-remove`/`lr-retry` event is about via the
|
|
65
71
|
platform's own `id` attribute/property rather than a second, differently-named prop. Set `id="..."`
|
|
66
72
|
when you have a stable server-side attachment id; when unset and `file` is set, a stable id is
|
|
@@ -73,7 +79,9 @@ mimeType, src }`, emitted when the preview action opens the document viewer)
|
|
|
73
79
|
|
|
74
80
|
**Slots:** none.
|
|
75
81
|
|
|
76
|
-
**CSS parts:** `base`, `thumbnail`, `meta`, `name`, `size
|
|
82
|
+
**CSS parts:** `base`, `thumbnail`, `meta`, `name`, `size` (the formatted `bytes` count; the part
|
|
83
|
+
keeps its pre-rename name — it is the rendered size *text*, and renaming a part would break shipped
|
|
84
|
+
`::part()` rules for no gain), `status-text` (the visible text twin of
|
|
77
85
|
the status accent color, so the state is carried in words and not only in color; empty and hidden
|
|
78
86
|
for `pending`/`done`), `progress`, `progress-fill`, `spinner` (decorative/`aria-hidden` while the
|
|
79
87
|
adjacent `status-text` supplies the wording), `retry-button`, `preview-button`,
|
|
@@ -116,13 +124,13 @@ decimal place), and a negative or non-finite input (`NaN`, `Infinity`) returns `
|
|
|
116
124
|
size renders nothing instead of `"NaN B"`.
|
|
117
125
|
|
|
118
126
|
```html
|
|
119
|
-
<lr-attachment-chip name="report.pdf"
|
|
127
|
+
<lr-attachment-chip name="report.pdf" bytes="245000" mime-type="application/pdf" status="done"></lr-attachment-chip>
|
|
120
128
|
<lr-attachment-chip id="att-2" status="uploading" progress="42"></lr-attachment-chip>
|
|
121
129
|
<script type="module">
|
|
122
130
|
import { formatFileSize } from '@aceshooting/lyra-ui/components/media/attachment-chip/file-size.js';
|
|
123
131
|
|
|
124
132
|
const chip = document.createElement('lr-attachment-chip');
|
|
125
|
-
chip.file = pickedFile; // name/
|
|
133
|
+
chip.file = pickedFile; // name/bytes/mime-type/thumbnail all derived from the File
|
|
126
134
|
chip.addEventListener('lr-remove', (e) => removeAttachment(e.detail.id));
|
|
127
135
|
chip.addEventListener('lr-retry', (e) => retryUpload(e.detail.id));
|
|
128
136
|
chip.addEventListener('lr-preview', (e) => console.log(e.detail));
|
|
@@ -139,10 +147,10 @@ or to `undefined`, and again on disconnect. Because the same pass that allocates
|
|
|
139
147
|
previous entry, reassigning `file` several times before the next paint leaks nothing.
|
|
140
148
|
|
|
141
149
|
**Known gotchas:**
|
|
142
|
-
- `file` always wins over `name`/`
|
|
150
|
+
- `file` always wins over `name`/`bytes`/`mimeType` when both are set — assigning those props while
|
|
143
151
|
`file` is also set has no visible effect on the rendered chip.
|
|
144
|
-
- A `0
|
|
145
|
-
empty file"); the `size` part is hidden entirely rather than showing a literal `"0 B"`.
|
|
152
|
+
- A `0` `bytes` value and an unset `bytes` value are indistinguishable (there's no separate flag for
|
|
153
|
+
"genuinely empty file"); the `size` part is hidden entirely rather than showing a literal `"0 B"`.
|
|
146
154
|
- `progress` only renders as a numeric bar when `status="uploading"` **and** `progress` is finite
|
|
147
155
|
and `> 0`; otherwise it's either nothing (non-`uploading` status) or the indeterminate spinner
|
|
148
156
|
(`uploading` with no known progress).
|