@khanacademy/perseus 77.0.1 → 77.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/zoom-image-button.d.ts +2 -0
- package/dist/components/zoomed-image-view.d.ts +2 -0
- package/dist/es/index.css +2 -2
- package/dist/es/index.css.map +1 -1
- package/dist/es/index.js +5 -5
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +2 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/es/index.js
CHANGED
|
@@ -1608,11 +1608,11 @@ function isGif(url){return url.endsWith(".gif")}function isSvg(url){const hasSvg
|
|
|
1608
1608
|
|
|
1609
1609
|
var styles$B = {"contentWrapper":"perseus_2D3jnXMR","imageContainer":"perseus_E11qN2-o"};
|
|
1610
1610
|
|
|
1611
|
-
const ZoomedImageView=props=>{const i18n=usePerseusI18n();const scaleFF=isFeatureOn({apiOptions:props.apiOptions},"image-widget-upgrade-scale");const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$B.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$B.imageContainer,style:{width:
|
|
1611
|
+
const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const scaleFF=isFeatureOn({apiOptions:props.apiOptions},"image-widget-upgrade-scale");const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const effectiveScale=scaleFF?scale:1;const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*effectiveScale);const scaleHeight=maxAvailableHeight/(height*effectiveScale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedWidth=width*fitRatio;const constrainedHeight=height*fitRatio;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$B.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$B.imageContainer,style:{width:constrainedWidth*effectiveScale},children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",tabIndex:0,id:initialFocusId,children:jsxRuntimeExports.jsx(SvgImage,{...svgProps,allowZoom:false,width:constrainedWidth,height:constrainedHeight,scale:effectiveScale})})}),jsxRuntimeExports.jsx(IconButton,{icon:closeIcon,onClick:onClose,"aria-label":i18n.strings.imageResetZoomAriaLabel,kind:"primary",style:wbStyles$2.closeButton})]})})})};const wbStyles$2=StyleSheet.create({dialog:{width:"auto",height:"auto",margin:sizing.size_320,"@media (max-width: 767px)":{margin:0}},closeButton:{position:"absolute",top:border$1.width.medium,right:border$1.width.medium,opacity:0,":hover":{opacity:1},":focus":{opacity:1}}});
|
|
1612
1612
|
|
|
1613
1613
|
const ZoomImageButton=props=>{const{imgSrc}=props;const i18n=usePerseusI18n();const uniqueId=React.useId().replace(/:/g,"");const zoomedImageUniqueId=`zoomed-image-${uniqueId}`;const handleClick=(event,openModal)=>{const mouseEvent=event;if(mouseEvent.metaKey||mouseEvent.ctrlKey){window.open(imgSrc,"_blank");}else {openModal();}};return jsxRuntimeExports.jsx(ModalLauncher,{initialFocusId:zoomedImageUniqueId,modal:({closeModal})=>jsxRuntimeExports.jsx(ZoomedImageView,{...props,initialFocusId:zoomedImageUniqueId,onClose:closeModal}),children:({openModal})=>jsxRuntimeExports.jsx(Clickable,{"aria-label":i18n.strings.imageZoomAriaLabel,onClick:event=>handleClick(event,openModal),style:{position:"absolute",width:"100%",height:"100%",overflow:"hidden",cursor:"zoom-in"},children:()=>{return jsxRuntimeExports.jsx(React.Fragment,{})}})})};
|
|
1614
1614
|
|
|
1615
|
-
function isImageProbablyPhotograph(imageUrl){return /\.(jpg|jpeg)$/i.test(imageUrl)}function defaultPreloader(dimensions){return jsxRuntimeExports.jsx("span",{style:{top:0,left:0,width:"100%",height:"100%",position:"absolute",minWidth:"20px",display:"flex",justifyContent:"center",alignContent:"center"},children:jsxRuntimeExports.jsx(CircularSpinner,{size:"medium"})})}class SvgImage extends React.Component{componentDidMount(){this._isMounted=true;if(Util.isLabeledSVG(this.props.src)){this.loadResources();}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.src!==nextProps.src){this._isLoadingGraphie=false;this.setState({imageLoaded:false,dataLoaded:false});}}shouldComponentUpdate(nextProps,nextState){if(!_.isEqual(this.props,nextProps)){return true}const wasLoaded=this.isLoadedInState(this.state);const nextLoaded=this.isLoadedInState(nextState);return wasLoaded!==nextLoaded}componentDidUpdate(prevProps,prevState){const wasLoaded=this.isLoadedInState(prevState);const isLoaded=this.isLoadedInState(this.state);if(Util.isLabeledSVG(this.props.src)&&!isLoaded&&!this._isLoadingGraphie){this.loadResources();}if(!wasLoaded&&isLoaded){this.props.setAssetStatus(this.props.src,true);}}componentWillUnmount(){this._isMounted=false;}isLoadedInState(state){return Util.isLabeledSVG(this.props.src)?state.imageLoaded&&state.dataLoaded:state.imageLoaded}loadResources(){this._isLoadingGraphie=true;loadGraphie(this.props.src,(data,localized)=>{this._isLoadingGraphie=false;if(this._isMounted&&data.labels&&data.range){const labelsRendered={};data.labels.forEach(label=>{labelsRendered[label.content]=false;});this.setState({dataLoaded:true,labelDataIsLocalized:localized,labelsRendered,labels:data.labels,range:data.range});}});}sizeProvided(){return this.props.width!=null&&this.props.height!=null}_tryGetPixels(value){value=value||"";if(!value.endsWith("px")){return null}return parseFloat(value)||null}render(){const imageSrc=this.props.src;const imageProps={alt:this.props.alt,title:this.props.title};const width=this.props.width&&this.props.width*this.props.scale;const height=this.props.height&&this.props.height*this.props.scale;const dimensions={width,height};const responsive=this.props.responsive&&!!(width&&height);let extraGraphie;if(this.props.extraGraphie&&this.props.extraGraphie.labels.length){extraGraphie=jsxRuntimeExports.jsx(Graphie,{box:this.props.extraGraphie.box,range:this.props.extraGraphie.range,options:{labels:this.props.extraGraphie.labels},responsive:true,addMouseLayer:false,setup:this.setupGraphie});}const preloaderBaseFunc=this.props.preloader===undefined?defaultPreloader:this.props.preloader;const preloader=preloaderBaseFunc?()=>preloaderBaseFunc(dimensions):null;if(!Util.isLabeledSVG(imageSrc)){if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,imgProps:imageProps,preloader:preloader,onUpdate:this.handleUpdate}),extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,allowFullBleed:this.props.allowFullBleed&&isImageProbablyPhotograph(imageSrc),scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageSrc})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,preloader:preloader,imgProps:imageProps,onUpdate:this.handleUpdate})}const imageUrl=Util.getSvgUrl(imageSrc);let graphie;if(this.isLoadedInState(this.state)){let box;if(this.sizeProvided()){box=[width,height];}else if(this.state.imageDimensions){box=[this.state.imageDimensions[0]*this.props.scale,this.state.imageDimensions[1]*this.props.scale];}else {throw new PerseusError("svg-image has no dimensions",Errors.InvalidInput,{metadata:{src:this.props.src}})}graphie=jsxRuntimeExports.jsx(Graphie,{ref:"graphie",box:box,scale:[40*this.props.scale,40*this.props.scale],range:this.state.range,options:_.pick(this.state,"labels"),responsive:responsive,addMouseLayer:false,setup:this.setupGraphie});}if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:preloader,imgProps:imageProps}),graphie,extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageUrl})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsxs("div",{className:"unresponsive-svg-image",style:dimensions,children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:preloader,imgProps:imageProps}),graphie]})}constructor(props){super(props),this.onImageLoad=()=>{if(this.sizeProvided()){this.setState({imageLoaded:true});}else {Util.getImageSize(this.props.src,(width,height)=>{if(this._isMounted){this.setState({imageLoaded:true,imageDimensions:[width,height]});}});}},this.setupGraphie=(graphie,options)=>{const newLabelsRendered={};_.map(options.labels,labelData=>{const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.state.labelDataIsLocalized){const elem=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,false);getDependencies().svgImageJiptLabels.addLabel(elem,labelData.typesetAsMath);}else if(labelData.coordinates){const styling=this.props.scale!==1?{"font-size":100*this.props.scale+"%"}:null;const label=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,labelData.typesetAsMath,styling);const labelStyle=label[0].style;let labelTop=this._tryGetPixels(labelStyle.top);let labelLeft=this._tryGetPixels(labelStyle.left);if(labelTop===null||labelLeft===null){const labelPosition=label.position();labelTop=labelPosition.top;labelLeft=labelPosition.left;}const svgHeight=(this.props.height||0)*this.props.scale;const svgWidth=(this.props.width||0)*this.props.scale;label.css({top:labelTop/svgHeight*100+"%",left:labelLeft/svgWidth*100+"%"});_.each(labelData.style,(styleValue,styleName)=>{label.css(styleName,styleValue);});}newLabelsRendered[labelData.content]=true;});this.setState(prev=>({labelsRendered:{...prev.labelsRendered,...newLabelsRendered}}));},this.handleUpdate=status=>{this.props.onUpdate();if(!Util.isLabeledSVG(this.props.src)&&status==="loaded"){this.setState({imageLoaded:true});}};props.setAssetStatus(props.src,false);this._isMounted=false;this._isLoadingGraphie=false;this.state={imageLoaded:false,imageDimensions:null,dataLoaded:false,labelDataIsLocalized:false,labels:[],labelsRendered:{},range:[[0,0],[0,0]]};}}SvgImage.contextType=PerseusI18nContext;SvgImage.defaultProps={constrainHeight:false,onUpdate:()=>{},responsive:true,src:"",scale:1,zoomToFullSizeOnMobile:false,setAssetStatus:(src,status)=>{}};
|
|
1615
|
+
function isImageProbablyPhotograph(imageUrl){return /\.(jpg|jpeg)$/i.test(imageUrl)}function defaultPreloader(dimensions){return jsxRuntimeExports.jsx("span",{style:{top:0,left:0,width:"100%",height:"100%",position:"absolute",minWidth:"20px",display:"flex",justifyContent:"center",alignContent:"center"},children:jsxRuntimeExports.jsx(CircularSpinner,{size:"medium"})})}class SvgImage extends React.Component{componentDidMount(){this._isMounted=true;if(Util.isLabeledSVG(this.props.src)){this.loadResources();}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.src!==nextProps.src){this._isLoadingGraphie=false;this.setState({imageLoaded:false,dataLoaded:false});}}shouldComponentUpdate(nextProps,nextState){if(!_.isEqual(this.props,nextProps)){return true}const wasLoaded=this.isLoadedInState(this.state);const nextLoaded=this.isLoadedInState(nextState);return wasLoaded!==nextLoaded}componentDidUpdate(prevProps,prevState){const wasLoaded=this.isLoadedInState(prevState);const isLoaded=this.isLoadedInState(this.state);if(Util.isLabeledSVG(this.props.src)&&!isLoaded&&!this._isLoadingGraphie){this.loadResources();}if(!wasLoaded&&isLoaded){this.props.setAssetStatus(this.props.src,true);}}componentWillUnmount(){this._isMounted=false;}isLoadedInState(state){return Util.isLabeledSVG(this.props.src)?state.imageLoaded&&state.dataLoaded:state.imageLoaded}loadResources(){this._isLoadingGraphie=true;loadGraphie(this.props.src,(data,localized)=>{this._isLoadingGraphie=false;if(this._isMounted&&data.labels&&data.range){const labelsRendered={};data.labels.forEach(label=>{labelsRendered[label.content]=false;});this.setState({dataLoaded:true,labelDataIsLocalized:localized,labelsRendered,labels:data.labels,range:data.range});}});}sizeProvided(){return this.props.width!=null&&this.props.height!=null}_tryGetPixels(value){value=value||"";if(!value.endsWith("px")){return null}return parseFloat(value)||null}render(){const imageSrc=this.props.src;const imageProps={alt:this.props.alt,title:this.props.title};const width=this.props.width&&this.props.width*this.props.scale;const height=this.props.height&&this.props.height*this.props.scale;const dimensions={width,height};const responsive=this.props.responsive&&!!(width&&height);let extraGraphie;if(this.props.extraGraphie&&this.props.extraGraphie.labels.length){extraGraphie=jsxRuntimeExports.jsx(Graphie,{box:this.props.extraGraphie.box,range:this.props.extraGraphie.range,options:{labels:this.props.extraGraphie.labels},responsive:true,addMouseLayer:false,setup:this.setupGraphie});}const preloaderBaseFunc=this.props.preloader===undefined?defaultPreloader:this.props.preloader;const preloader=preloaderBaseFunc?()=>preloaderBaseFunc(dimensions):null;if(!Util.isLabeledSVG(imageSrc)){if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,imgProps:imageProps,preloader:preloader,onUpdate:this.handleUpdate}),extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,allowFullBleed:this.props.allowFullBleed&&isImageProbablyPhotograph(imageSrc),scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageSrc,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,preloader:preloader,imgProps:imageProps,onUpdate:this.handleUpdate})}const imageUrl=Util.getSvgUrl(imageSrc);let graphie;if(this.isLoadedInState(this.state)){let box;if(this.sizeProvided()){box=[width,height];}else if(this.state.imageDimensions){box=[this.state.imageDimensions[0]*this.props.scale,this.state.imageDimensions[1]*this.props.scale];}else {throw new PerseusError("svg-image has no dimensions",Errors.InvalidInput,{metadata:{src:this.props.src}})}graphie=jsxRuntimeExports.jsx(Graphie,{ref:"graphie",box:box,scale:[40*this.props.scale,40*this.props.scale],range:this.state.range,options:_.pick(this.state,"labels"),responsive:responsive,addMouseLayer:false,setup:this.setupGraphie});}if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:preloader,imgProps:imageProps}),graphie,extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageUrl,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsxs("div",{className:"unresponsive-svg-image",style:dimensions,children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:preloader,imgProps:imageProps}),graphie]})}constructor(props){super(props),this.onImageLoad=()=>{if(this.sizeProvided()){this.setState({imageLoaded:true});}else {Util.getImageSize(this.props.src,(width,height)=>{if(this._isMounted){this.setState({imageLoaded:true,imageDimensions:[width,height]});}});}},this.setupGraphie=(graphie,options)=>{const newLabelsRendered={};_.map(options.labels,labelData=>{const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.state.labelDataIsLocalized){const elem=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,false);getDependencies().svgImageJiptLabels.addLabel(elem,labelData.typesetAsMath);}else if(labelData.coordinates){const styling=this.props.scale!==1?{"font-size":100*this.props.scale+"%"}:null;const label=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,labelData.typesetAsMath,styling);const labelStyle=label[0].style;let labelTop=this._tryGetPixels(labelStyle.top);let labelLeft=this._tryGetPixels(labelStyle.left);if(labelTop===null||labelLeft===null){const labelPosition=label.position();labelTop=labelPosition.top;labelLeft=labelPosition.left;}const svgHeight=(this.props.height||0)*this.props.scale;const svgWidth=(this.props.width||0)*this.props.scale;label.css({top:labelTop/svgHeight*100+"%",left:labelLeft/svgWidth*100+"%"});_.each(labelData.style,(styleValue,styleName)=>{label.css(styleName,styleValue);});}newLabelsRendered[labelData.content]=true;});this.setState(prev=>({labelsRendered:{...prev.labelsRendered,...newLabelsRendered}}));},this.handleUpdate=status=>{this.props.onUpdate();if(!Util.isLabeledSVG(this.props.src)&&status==="loaded"){this.setState({imageLoaded:true});}};props.setAssetStatus(props.src,false);this._isMounted=false;this._isLoadingGraphie=false;this.state={imageLoaded:false,imageDimensions:null,dataLoaded:false,labelDataIsLocalized:false,labels:[],labelsRendered:{},range:[[0,0],[0,0]]};}}SvgImage.contextType=PerseusI18nContext;SvgImage.defaultProps={constrainHeight:false,onUpdate:()=>{},responsive:true,src:"",scale:1,zoomToFullSizeOnMobile:false,setAssetStatus:(src,status)=>{}};
|
|
1616
1616
|
|
|
1617
1617
|
class Tex extends React.Component{render(){const{TeX:BaseTeX}=getDependencies();return jsxRuntimeExports.jsx(BaseTeX,{onRender:this.handleRender,children:this.props.children})}constructor(props){super(props),this.handleRender=()=>{this.setState({rendered:true});this.props.onRender();if(!this._hasRendered){this._hasRendered=true;this.props.setAssetStatus(this.props.children,true);}};this.props.setAssetStatus(this.props.children,false);this.state={rendered:false};this._hasRendered=false;}}Tex.defaultProps={onRender:()=>{},setAssetStatus:(src,status)=>{}};
|
|
1618
1618
|
|
|
@@ -1842,9 +1842,9 @@ const ExploreImageModal=props=>{const context=React__default.useContext(PerseusI
|
|
|
1842
1842
|
|
|
1843
1843
|
const GifControlsIcon=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(IconButton,{icon:isPlaying?pauseIcon:playIcon,kind:"secondary","aria-label":isPlaying?strings.gifPauseButtonLabel:strings.gifPlayButtonLabel,onClick:onToggle,style:{flexShrink:0}})};
|
|
1844
1844
|
|
|
1845
|
-
const ImageInfoArea=props=>{const{backgroundImage,caption,longDescription,apiOptions,linterContext,
|
|
1845
|
+
const ImageInfoArea=props=>{const{backgroundImage,caption,longDescription,apiOptions,linterContext,isGifPlaying,setIsGifPlaying}=props;const context=React.useContext(PerseusI18nContext);const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);return jsxRuntimeExports.jsxs("div",{className:styles$g.infoAreaContainer,children:[gifControlsFF&&imageIsGif&&jsxRuntimeExports.jsx(GifControlsIcon,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),gifControlsFF&&imageIsGif&&longDescription&&jsxRuntimeExports.jsx("div",{className:styles$g.spacerHorizontal}),longDescription&&jsxRuntimeExports.jsx(ModalLauncher,{modal:jsxRuntimeExports.jsx(ExploreImageModal,{...props}),children:({openModal})=>jsxRuntimeExports.jsx(ExploreImageButton,{hasCaption:!!caption,onClick:openModal})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
|
|
1846
1846
|
|
|
1847
|
-
const ImageComponent=props=>{const{apiOptions,alt,backgroundImage,box,caption,longDescription,decorative,linterContext,labels,range,title,trackInteraction,widgetId}=props;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");const scaleFF=isFeatureOn({apiOptions},"image-widget-upgrade-scale");const[zoomSize,setZoomSize]=React.useState([backgroundImage.width||0,backgroundImage.height||0]);const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[zoomWidth,zoomHeight]=zoomSize;const ignoreResultsRef=React.useRef(false);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React.useEffect(()=>{ignoreResultsRef.current=false;Util.getImageSizeModern(backgroundImage.url).then(naturalSize=>{if(ignoreResultsRef.current){return}const[naturalWidth,naturalHeight]=naturalSize;const[savedWidth,savedHeight]=[backgroundImage.width||0,backgroundImage.height||0];if(naturalWidth>savedWidth){setZoomSize([naturalWidth,naturalHeight]);}else {setZoomSize([savedWidth,savedHeight]);}});return ()=>{ignoreResultsRef.current=true;}},[backgroundImage.url,backgroundImage.width,backgroundImage.height]);if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);let scale=props.scale;if(!scaleFF||scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,apiOptions:apiOptions,width:scaleFF?backgroundImage.width:zoomWidth,height:scaleFF?backgroundImage.height:zoomHeight,scale:scale,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus})});const maxWidth=backgroundImage.width?backgroundImage.width*scale:undefined;if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth},children:svgImage})}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth},children:[title&&jsxRuntimeExports.jsx("div",{className:`perseus-image-title ${styles$g.titleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),svgImage,(gifControlsFF&&imageIsGif||caption||longDescription)&&jsxRuntimeExports.jsx(ImageInfoArea,{zoomSize:zoomSize,isGifPlaying:isGifPlaying,setIsGifPlaying:setIsGifPlaying,...props})]})};
|
|
1847
|
+
const ImageComponent=props=>{const{apiOptions,alt,backgroundImage,box,caption,longDescription,decorative,linterContext,labels,range,title,trackInteraction,widgetId}=props;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");const scaleFF=isFeatureOn({apiOptions},"image-widget-upgrade-scale");const[zoomSize,setZoomSize]=React.useState([backgroundImage.width||0,backgroundImage.height||0]);const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[zoomWidth,zoomHeight]=zoomSize;const ignoreResultsRef=React.useRef(false);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React.useEffect(()=>{ignoreResultsRef.current=false;Util.getImageSizeModern(backgroundImage.url).then(naturalSize=>{if(ignoreResultsRef.current){return}const[naturalWidth,naturalHeight]=naturalSize;const[savedWidth,savedHeight]=[backgroundImage.width||0,backgroundImage.height||0];if(naturalWidth>savedWidth){setZoomSize([naturalWidth,naturalHeight]);}else {setZoomSize([savedWidth,savedHeight]);}});return ()=>{ignoreResultsRef.current=true;}},[backgroundImage.url,backgroundImage.width,backgroundImage.height]);if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);let scale=props.scale;if(!scaleFF||scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,apiOptions:apiOptions,width:scaleFF?backgroundImage.width:zoomWidth,height:scaleFF?backgroundImage.height:zoomHeight,scale:scale,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus})});const maxWidth=backgroundImage.width?backgroundImage.width*scale:undefined;const width=maxWidth?undefined:"fit-content";if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth,width:width},children:svgImage})}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth,width:width},children:[title&&jsxRuntimeExports.jsx("div",{className:`perseus-image-title ${styles$g.titleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),svgImage,(gifControlsFF&&imageIsGif||caption||longDescription)&&jsxRuntimeExports.jsx(ImageInfoArea,{zoomSize:zoomSize,isGifPlaying:isGifPlaying,setIsGifPlaying:setIsGifPlaying,...props})]})};
|
|
1848
1848
|
|
|
1849
1849
|
const defaultBoxSize=400;const defaultRange=[0,10];const defaultBackgroundImage$1={url:null,width:0,height:0};class ImageWidget extends React.Component{getPromptJSON(){return getPromptJSON$d(this.props)}render(){return jsxRuntimeExports.jsx(ImageComponent,{...this.props})}constructor(...args){super(...args),this.isWidget=true;}}ImageWidget.contextType=PerseusI18nContext;ImageWidget.defaultProps={alignment:"block",title:"",range:[defaultRange,defaultRange],box:[defaultBoxSize,defaultBoxSize],backgroundImage:defaultBackgroundImage$1,scale:1,labels:[],alt:"",longDescription:"",decorative:false,caption:"",linterContext:linterContextDefault};var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
|
|
1850
1850
|
|
|
@@ -2058,7 +2058,7 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
|
|
|
2058
2058
|
|
|
2059
2059
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2060
2060
|
|
|
2061
|
-
const libName="@khanacademy/perseus";const libVersion="77.0.
|
|
2061
|
+
const libName="@khanacademy/perseus";const libVersion="77.0.2";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2062
2062
|
|
|
2063
2063
|
const apiVersion={major:12,minor:0};
|
|
2064
2064
|
|