@khanacademy/perseus 72.6.7 → 72.7.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/dist/es/index.js CHANGED
@@ -2082,7 +2082,7 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
2082
2082
 
2083
2083
  const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
2084
2084
 
2085
- const libName="@khanacademy/perseus";const libVersion="72.6.7";addLibraryVersionToPerseusDebug(libName,libVersion);
2085
+ const libName="@khanacademy/perseus";const libVersion="72.7.0";addLibraryVersionToPerseusDebug(libName,libVersion);
2086
2086
 
2087
2087
  const apiVersion={major:12,minor:0};
2088
2088
 
@@ -2092,9 +2092,9 @@ registerWidgets(allWidgets);const ItemVersion=getVersionVector();
2092
2092
 
2093
2093
  class ArticleRenderer extends React.Component{componentDidMount(){this._currentFocus=null;}shouldComponentUpdate(nextProps){return nextProps!==this.props}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,isArticle:true};const classes=classNames$1({"framework-perseus":true,"perseus-article":true,[ClassNames.MOBILE]:apiOptions.isMobile});const sections=this._sections().map((section,sectionIndex)=>{return jsxRuntimeExports.jsx("div",{className:"clearfix",children:jsxRuntimeExports.jsx(UserInputManager,{widgets:section.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>createElement(Renderer,{...section,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:elem=>{if(elem){this.sectionRenderers[sectionIndex]=elem;}},key:sectionIndex,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,onFocusChange:(newFocusPath,oldFocusPath)=>{this._handleFocusChange(newFocusPath&&[sectionIndex].concat(newFocusPath),oldFocusPath&&[sectionIndex].concat(oldFocusPath));}},linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"article"),legacyPerseusLint:this.props.legacyPerseusLint,strings:this.context.strings})})},sectionIndex)});return jsxRuntimeExports.jsx("div",{className:classes,children:jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:sections})})}constructor(props){super(props),this.sectionRenderers=[],this._handleFocusChange=(newFocusPath,oldFocusPath)=>{if(newFocusPath){this._setCurrentFocus(newFocusPath);}else {this._onRendererBlur(oldFocusPath);}},this._setCurrentFocus=newFocusPath=>{const{keypadElement,apiOptions}=this.props;const{isMobile}=apiOptions;const prevFocusPath=this._currentFocus;this._currentFocus=newFocusPath;let didFocusInput=false;let focusedInput;if(this._currentFocus){const[sectionIndex,...focusPath]=this._currentFocus;const inputPaths=this.sectionRenderers[sectionIndex].getInputPaths();didFocusInput=inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,focusPath)});focusedInput=this.sectionRenderers[sectionIndex].getDOMNodeForPath(focusPath);}const{onFocusChange}=this.props.apiOptions;if(onFocusChange){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocusPath,keypadHeight,didFocusInput?focusedInput:null);},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}},this._onRendererBlur=blurPath=>{const blurringFocusPath=this._currentFocus;if(!Util.inputPathsEqual(blurPath,blurringFocusPath)){return}setTimeout(()=>{if(Util.inputPathsEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.blur=()=>{if(this._currentFocus){const[sectionIndex,...inputPath]=this._currentFocus;this.sectionRenderers[sectionIndex].blurPath(inputPath);}},this._sections=()=>{const sections=Array.isArray(this.props.json)?this.props.json:[this.props.json];if(getDependencies().JIPT.useJIPT){const paragraphs=[];for(const section of sections){JiptParagraphs.parseToArray(section.content).forEach(paragraph=>{paragraphs.push({...section,content:paragraph});});}return paragraphs}return sections};}}ArticleRenderer.contextType=PerseusI18nContext;ArticleRenderer.defaultProps={apiOptions:ApiOptions.defaults,useNewStyles:false,linterContext:PerseusLinter.linterContextDefault};
2094
2094
 
2095
- class HintRenderer extends React.Component{render(){const{apiOptions,className,hint,lastHint,lastRendered,pos,totalHints}=this.props;const{isMobile}=apiOptions;const classNames=classNames$1("hint",!isMobile&&"perseus-hint-renderer",isMobile&&css(styles$2.newHint),isMobile&&lastRendered&&css(styles$2.lastRenderedNewHint),lastHint&&"last-hint",lastRendered&&"last-rendered",className);const rendererApiOptions={...apiOptions,customKeypad:false};return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:classNames,tabIndex:"-1",children:[!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:this.context.strings.hintPos({pos:pos+1})}),!apiOptions.isMobile&&totalHints!=null&&pos!=null&&jsxRuntimeExports.jsx("span",{className:"perseus-hint-label",style:{display:"block",color:apiOptions.hintProgressColor},children:`${pos+1} / ${totalHints}`}),jsxRuntimeExports.jsx(UserInputManager,{widgets:hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{ref:this.rendererRef,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,widgets:hint.widgets,content:hint.content||"",images:hint.images,apiOptions:rendererApiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hint"),strings:this.context.strings})})]})})}constructor(...args){super(...args),this.rendererRef=React.createRef(),this.getSerializedState=()=>{return this.rendererRef.current?.getSerializedState()};}}HintRenderer.contextType=PerseusI18nContext;HintRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$2=StyleSheet.create({newHint:{marginBottom:1.5*baseUnitPx,borderLeftColor:gray97,borderLeftStyle:"solid",borderLeftWidth:hintBorderWidth,[mediaQueries.lgOrSmaller]:{paddingLeft:baseUnitPx},[mediaQueries.smOrSmaller]:{paddingLeft:0},":focus":{outline:"none"}},lastRenderedNewHint:{marginBottom:0,borderLeftColor:kaGreen}});
2095
+ class HintRenderer extends React.Component{render(){if(this.props.hint.placeholder){return jsxRuntimeExports.jsx("span",{})}const{apiOptions,className,hint,lastHint,lastRendered,pos,totalHints}=this.props;const{isMobile}=apiOptions;const classNames=classNames$1("hint",!isMobile&&"perseus-hint-renderer",isMobile&&css(styles$2.newHint),isMobile&&lastRendered&&css(styles$2.lastRenderedNewHint),lastHint&&"last-hint",lastRendered&&"last-rendered",className);const rendererApiOptions={...apiOptions,customKeypad:false};return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:classNames,tabIndex:"-1",children:[!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:this.context.strings.hintPos({pos:pos+1})}),!apiOptions.isMobile&&totalHints!=null&&pos!=null&&jsxRuntimeExports.jsx("span",{className:"perseus-hint-label",style:{display:"block",color:apiOptions.hintProgressColor},children:`${pos+1} / ${totalHints}`}),jsxRuntimeExports.jsx(UserInputManager,{widgets:hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{ref:this.rendererRef,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,widgets:hint.widgets,content:hint.content||"",images:hint.images,apiOptions:rendererApiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hint"),strings:this.context.strings})})]})})}constructor(...args){super(...args),this.rendererRef=React.createRef(),this.getSerializedState=()=>{return this.rendererRef.current?.getSerializedState()};}}HintRenderer.contextType=PerseusI18nContext;HintRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$2=StyleSheet.create({newHint:{marginBottom:1.5*baseUnitPx,borderLeftColor:gray97,borderLeftStyle:"solid",borderLeftWidth:hintBorderWidth,[mediaQueries.lgOrSmaller]:{paddingLeft:baseUnitPx},[mediaQueries.smOrSmaller]:{paddingLeft:0},":focus":{outline:"none"}},lastRenderedNewHint:{marginBottom:0,borderLeftColor:kaGreen}});
2096
2096
 
2097
- class HintsRenderer extends React.Component{componentDidMount(){this._cacheHintImages();}UNSAFE_componentWillReceiveProps(nextProps){if(nextProps.hintsVisible-this.props.hintsVisible>1){this.setState({isFinalHelpPage:true});}}componentDidUpdate(prevProps,prevState){if(!_.isEqual(prevProps.hints,this.props.hints)||prevProps.hintsVisible!==this.props.hintsVisible){this._cacheHintImages();}const prevHintsVisible=prevProps.hintsVisible||0;const nextHintsVisible=this.props.hintsVisible||0;if(prevHintsVisible<nextHintsVisible&&nextHintsVisible<=this.props.hints.length&&nextHintsVisible>=0){const pos=nextHintsVisible-1;ReactDOM__default.findDOMNode(this.refs["hintRenderer"+pos]).focus();}}render(){const apiOptions=this.getApiOptions();const hintsVisible=this._hintsVisible();const hints=[];const isFinalHelpPage=this.state.isFinalHelpPage;this.props.hints.slice(0,hintsVisible).forEach((hint,i)=>{const lastHint=i===this.props.hints.length-1&&!/\*\*/.test(hint.content);const lastRendered=i===hintsVisible-1;const renderer=jsxRuntimeExports.jsx(HintRenderer,{dependencies:this.props.dependencies,lastHint:lastHint,lastRendered:lastRendered,hint:hint,pos:i,totalHints:this.props.hints.length,ref:"hintRenderer"+i,apiOptions:apiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints["+i+"]")},"hintRenderer"+i);if(isFinalHelpPage){hints.push(renderer);}else {if(hint.replace&&hints.length>0){hints[hints.length-1]=renderer;}else {hints.push(renderer);}}});const{getAnotherHint}=apiOptions;const showGetAnotherHint=getAnotherHint&&hintsVisible>0&&hintsVisible<this.props.hints.length;const hintRatioCopy=`(${hintsVisible}/${this.props.hints.length})`;const classNames=classNames$1(this.props.className,apiOptions.isMobile&&hintsVisible>0&&css(styles$1.mobileHintStylesHintsRenderer));return jsxRuntimeExports.jsxs("div",{className:classNames,children:[apiOptions.isMobile&&hintsVisible>0&&jsxRuntimeExports.jsx("div",{className:css(styles$1.mobileHintStylesHintTitle,sharedStyles.responsiveLabel),children:this.context.strings.hints}),hints,showGetAnotherHint&&jsxRuntimeExports.jsxs("button",{rel:"button",className:css(styles$1.linkButton,styles$1.getAnotherHintButton,apiOptions.isMobile&&styles$1.mobileHintStylesGetAnotherHintButton),onClick:evt=>{evt.preventDefault();evt.stopPropagation();if(getAnotherHint){getAnotherHint();}},children:[jsxRuntimeExports.jsx("span",{className:css(styles$1.plusText,apiOptions.isMobile&&styles$1.mobileHintStylesPlusText),children:"+"}),jsxRuntimeExports.jsxs("span",{className:css(styles$1.getAnotherHintText),children:[this.context.strings.getAnotherHint," ",hintRatioCopy]})]})]})}constructor(...args){super(...args),this.state={isFinalHelpPage:false},this._hintsVisible=()=>{if(this.props.hintsVisible==null||this.props.hintsVisible===-1){return this.props.hints.length}return this.props.hintsVisible},this._cacheImagesInHint=hint=>{_.each(hint.images,(data,src)=>{const image=new Image;image.src=Util.getRealImageUrl(src);});},this._cacheHintImages=()=>{if(this._hintsVisible()>0){_.each(this.props.hints,this._cacheImagesInHint);}else if(this.props.hints.length>0){this._cacheImagesInHint(this.props.hints[0]);}},this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions,readOnly:false}},this.getSerializedState=()=>{return _.times(this._hintsVisible(),i=>{return this.refs["hintRenderer"+i].getSerializedState()})};}}HintsRenderer.contextType=PerseusI18nContext;HintsRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const hintIndentation=baseUnitPx+hintBorderWidth;const styles$1=StyleSheet.create({rendererMargins:{marginTop:baseUnitPx},linkButton:{cursor:"pointer",border:"none",backgroundColor:"transparent",fontSize:"100%",fontFamily:"inherit",fontWeight:"bold",color:kaGreen,padding:0,position:"relative"},plusText:{fontSize:20,position:"absolute",top:-3,left:0},getAnotherHintText:{marginLeft:16},mobileHintStylesHintsRenderer:{marginTop:4*baseUnitPx,border:`solid ${gray85}`,borderWidth:"1px 0 0 0",position:"relative",":before":{content:'""',display:"table",clear:"both"},":after":{content:'""',display:"table",clear:"both"}},mobileHintStylesHintTitle:{fontFamily:"inherit",fontStyle:"normal",fontWeight:"bold",color:gray17,paddingTop:baseUnitPx,paddingBottom:1.5*baseUnitPx,[mediaQueries.lgOrSmaller]:{paddingLeft:0},[mediaQueries.smOrSmaller]:{paddingLeft:hintIndentation}},getAnotherHintButton:{marginTop:1.5*baseUnitPx},mobileHintStylesGetAnotherHintButton:{[mediaQueries.lgOrSmaller]:{paddingLeft:0},[mediaQueries.smOrSmaller]:{paddingLeft:hintIndentation}},mobileHintStylesPlusText:{[mediaQueries.lgOrSmaller]:{left:0},[mediaQueries.smOrSmaller]:{left:hintIndentation}}});
2097
+ class HintsRenderer extends React.Component{componentDidMount(){this._cacheHintImages();}UNSAFE_componentWillReceiveProps(nextProps){if(nextProps.hintsVisible-this.props.hintsVisible>1){this.setState({isFinalHelpPage:true});}}componentDidUpdate(prevProps,prevState){if(!_.isEqual(prevProps.hints,this.props.hints)||prevProps.hintsVisible!==this.props.hintsVisible){this._cacheHintImages();}const prevHintsVisible=prevProps.hintsVisible||0;const nextHintsVisible=this.props.hintsVisible||0;if(prevHintsVisible<nextHintsVisible&&nextHintsVisible<=this.props.hints.length&&nextHintsVisible>=0){const pos=nextHintsVisible-1;const hint=this.props.hints[pos];if(hint?.placeholder){return}try{const ref=this.refs["hintRenderer"+pos];if(ref==null){return}const domNode=ReactDOM__default.findDOMNode(ref);if(domNode&&typeof domNode.focus==="function"){domNode.focus();}}catch(e){}}}render(){const apiOptions=this.getApiOptions();const hintsVisible=this._hintsVisible();const hints=[];const isFinalHelpPage=this.state.isFinalHelpPage;this.props.hints.slice(0,hintsVisible).forEach((hint,i)=>{const lastHint=i===this.props.hints.length-1&&!/\*\*/.test(hint.content);const lastRendered=i===hintsVisible-1;const renderer=jsxRuntimeExports.jsx(HintRenderer,{dependencies:this.props.dependencies,lastHint:lastHint,lastRendered:lastRendered,hint:hint,pos:i,totalHints:this.props.hints.length,ref:"hintRenderer"+i,apiOptions:apiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints["+i+"]")},"hintRenderer"+i);if(isFinalHelpPage){hints.push(renderer);}else {if(hint.replace&&hints.length>0){hints[hints.length-1]=renderer;}else {hints.push(renderer);}}});const{getAnotherHint}=apiOptions;const showGetAnotherHint=getAnotherHint&&hintsVisible>0&&hintsVisible<this.props.hints.length;const hintRatioCopy=`(${hintsVisible}/${this.props.hints.length})`;const classNames=classNames$1(this.props.className,apiOptions.isMobile&&hintsVisible>0&&css(styles$1.mobileHintStylesHintsRenderer));return jsxRuntimeExports.jsxs("div",{className:classNames,children:[apiOptions.isMobile&&hintsVisible>0&&jsxRuntimeExports.jsx("div",{className:css(styles$1.mobileHintStylesHintTitle,sharedStyles.responsiveLabel),children:this.context.strings.hints}),hints,showGetAnotherHint&&jsxRuntimeExports.jsxs("button",{rel:"button",className:css(styles$1.linkButton,styles$1.getAnotherHintButton,apiOptions.isMobile&&styles$1.mobileHintStylesGetAnotherHintButton),onClick:evt=>{evt.preventDefault();evt.stopPropagation();if(getAnotherHint){getAnotherHint();}},children:[jsxRuntimeExports.jsx("span",{className:css(styles$1.plusText,apiOptions.isMobile&&styles$1.mobileHintStylesPlusText),children:"+"}),jsxRuntimeExports.jsxs("span",{className:css(styles$1.getAnotherHintText),children:[this.context.strings.getAnotherHint," ",hintRatioCopy]})]})]})}constructor(...args){super(...args),this.state={isFinalHelpPage:false},this._hintsVisible=()=>{if(this.props.hintsVisible==null||this.props.hintsVisible===-1){return this.props.hints.length}return this.props.hintsVisible},this._cacheImagesInHint=hint=>{_.each(hint.images,(data,src)=>{const image=new Image;image.src=Util.getRealImageUrl(src);});},this._cacheHintImages=()=>{if(this._hintsVisible()>0){_.each(this.props.hints,this._cacheImagesInHint);}else if(this.props.hints.length>0){this._cacheImagesInHint(this.props.hints[0]);}},this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions,readOnly:false}},this.getSerializedState=()=>{return _.times(this._hintsVisible(),i=>{return this.refs["hintRenderer"+i].getSerializedState()})};}}HintsRenderer.contextType=PerseusI18nContext;HintsRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const hintIndentation=baseUnitPx+hintBorderWidth;const styles$1=StyleSheet.create({rendererMargins:{marginTop:baseUnitPx},linkButton:{cursor:"pointer",border:"none",backgroundColor:"transparent",fontSize:"100%",fontFamily:"inherit",fontWeight:"bold",color:kaGreen,padding:0,position:"relative"},plusText:{fontSize:20,position:"absolute",top:-3,left:0},getAnotherHintText:{marginLeft:16},mobileHintStylesHintsRenderer:{marginTop:4*baseUnitPx,border:`solid ${gray85}`,borderWidth:"1px 0 0 0",position:"relative",":before":{content:'""',display:"table",clear:"both"},":after":{content:'""',display:"table",clear:"both"}},mobileHintStylesHintTitle:{fontFamily:"inherit",fontStyle:"normal",fontWeight:"bold",color:gray17,paddingTop:baseUnitPx,paddingBottom:1.5*baseUnitPx,[mediaQueries.lgOrSmaller]:{paddingLeft:0},[mediaQueries.smOrSmaller]:{paddingLeft:hintIndentation}},getAnotherHintButton:{marginTop:1.5*baseUnitPx},mobileHintStylesGetAnotherHintButton:{[mediaQueries.lgOrSmaller]:{paddingLeft:0},[mediaQueries.smOrSmaller]:{paddingLeft:hintIndentation}},mobileHintStylesPlusText:{[mediaQueries.lgOrSmaller]:{left:0},[mediaQueries.smOrSmaller]:{left:hintIndentation}}});
2098
2098
 
2099
2099
  const defaultContext={onRendered:isRendered=>{}};const context=React.createContext(defaultContext);
2100
2100