@khanacademy/perseus-editor 28.6.0 → 28.6.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/index.js
CHANGED
|
@@ -128,7 +128,7 @@ var xIcon__default = /*#__PURE__*/_interopDefaultCompat(xIcon);
|
|
|
128
128
|
var checkIcon__default = /*#__PURE__*/_interopDefaultCompat(checkIcon);
|
|
129
129
|
var minusCircleIcon__default = /*#__PURE__*/_interopDefaultCompat(minusCircleIcon);
|
|
130
130
|
|
|
131
|
-
const libName="@khanacademy/perseus-editor";const libVersion="28.6.
|
|
131
|
+
const libName="@khanacademy/perseus-editor";const libVersion="28.6.2";perseusUtils.addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
132
132
|
|
|
133
133
|
var jsxRuntime = {exports: {}};
|
|
134
134
|
|
|
@@ -1524,7 +1524,7 @@ const rendererProps=PropTypes__default.default.shape({content:PropTypes__default
|
|
|
1524
1524
|
|
|
1525
1525
|
const itemProps=PropTypes__default.default.shape({question:PropTypes__default.default.shape({}).isRequired,answerArea:PropTypes__default.default.shape({}).isRequired,hints:PropTypes__default.default.arrayOf(PropTypes__default.default.any).isRequired});class ItemDiff extends React__namespace.Component{render(){const{before,after}=this.props;const hintCount=Math.max(before.hints.length,after.hints.length);const question=jsxRuntimeExports.jsx(RendererDiff,{before:before.question,after:after.question,title:"Question",showAlignmentOptions:false,showSeparator:true});const extras=jsxRuntimeExports.jsx(WidgetDiff,{before:before.answerArea,after:after.answerArea,title:"Question extras"});const hints=___default.default.times(hintCount,function(n){return jsxRuntimeExports.jsx(RendererDiff,{before:n<before.hints.length?before.hints[n]:undefined,after:n<after.hints.length?after.hints[n]:undefined,title:`Hint ${n+1}`,showAlignmentOptions:false,showSeparator:n<hintCount-1},n)});return jsxRuntimeExports.jsx(perseus.Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:"framework-perseus",children:[question,extras,hints&&jsxRuntimeExports.jsx("div",{className:"diff-separator"}),hints]})})}}ItemDiff.propTypes={after:itemProps.isRequired,before:itemProps.isRequired};
|
|
1526
1526
|
|
|
1527
|
-
const{InfoTip: InfoTip$q,InlineIcon: InlineIcon$2}=perseus.components;class HintEditor extends React__namespace.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-hint-editor "+this.props.className,children:[this.props.showTitle&&jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Hint"}),jsxRuntimeExports.jsx(Editor,{ref:this.editor,apiOptions:this.props.apiOptions,widgets:this.props.widgets||undefined,content:this.props.content||undefined,images:this.props.images,replace:this.props.replace,placeholder:"Type your hint here...",imageUploader:this.props.imageUploader,onChange:this.props.onChange,widgetIsOpen:this.props.widgetIsOpen},this.props.itemId),jsxRuntimeExports.jsxs("div",{className:"hint-controls-container clearfix",children:[this.props.showMoveButtons&&jsxRuntimeExports.jsxs("span",{className:"reorder-hints",children:[jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isLast?"hidden":"",onClick:___default.default.partial(this.props.onMove,1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowDown})})," ",jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isFirst?"hidden":"",onClick:___default.default.partial(this.props.onMove,-1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowUp})})," ",this.props.isLast&&jsxRuntimeExports.jsx(InfoTip$q,{children:jsxRuntimeExports.jsx("p",{children:"The last hint is automatically bolded."})})]}),jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.replace,onChange:this.handleChange}),"Replace previous hint",this.props.showRemoveButton&&jsxRuntimeExports.jsxs("button",{type:"button",className:"remove-hint simple-button orange",onClick:this.props.onRemove,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...perseus.iconTrash}),"Remove this hint"," "]})]})]})}constructor(...args){super(...args),this.editor=React__namespace.createRef(),this.handleChange=e=>{this.props.onChange({replace:e.target.checked});},this.focus=()=>{this.editor.current?.focus();},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.serialize=options=>{return this.editor.current?.serialize(options)};}}HintEditor.defaultProps={className:"",content:"",replace:false,showMoveButtons:true,showTitle:true,showRemoveButton:true};class CombinedHintEditor extends React__namespace.Component{componentDidMount(){this.updatePreview();}componentDidUpdate(){this.updatePreview();}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";return jsxRuntimeExports.jsxs("div",{className:"perseus-combined-hint-editor "+"perseus-editor-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(HintEditor,{ref:this.editor,itemId:this.props.itemId,isFirst:this.props.isFirst,isLast:this.props.isLast,widgets:this.props.hint.widgets,content:this.props.hint.content,images:this.props.hint.images,replace:this.props.hint.replace,imageUploader:this.props.imageUploader,onChange:this.props.onChange,onRemove:this.props.onRemove,onMove:this.props.onMove,apiOptions:this.props.apiOptions,widgetIsOpen:this.props.widgetIsOpen})}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.deviceType,nochrome:true,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:this.frame,datasetKey:"mobile",datasetValue:isMobile,seamless:true,url:this.props.previewURL})})})]})}constructor(...args){super(...args),this.editor=React__namespace.createRef(),this.frame=React__namespace.createRef(),this.updatePreview=()=>{const shouldBold=this.props.isLast&&!/\*\*/.test(this.props.hint.content);this.frame.current?.sendNewData({type:"hint",data:{hint:this.props.hint,bold:shouldBold,pos:this.props.pos,apiOptions:this.props.apiOptions,linterContext:{contentType:"hint",highlightLint:this.props.highlightLint,paths:this.props.contentPaths}}});},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.serialize=options=>{return this.editor.current?.serialize(options)},this.focus=()=>{this.editor.current?.focus();};}}CombinedHintEditor.defaultProps={highlightLint:false};class CombinedHintsEditor extends React__namespace.Component{render(){const{itemId,hints}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const hintElems=___default.default.map(hints,function(hint,i){return jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(CombinedHintEditor,{ref:"hintEditor"+i,isFirst:i===0,isLast:i+1===hints.length,itemId:itemId,hint:hint,pos:i,imageUploader:this.props.imageUploader,onChange:this.handleHintChange.bind(this,i),onRemove:this.handleHintRemove.bind(this,i),onMove:this.handleHintMove.bind(this,i),deviceType:this.props.deviceType,apiOptions:this.props.apiOptions,highlightLint:this.props.highlightLint,previewURL:this.props.previewURL,contentPaths:[],widgetIsOpen:this.props.widgetIsOpen},"hintEditor"+i)}
|
|
1527
|
+
const{InfoTip: InfoTip$q,InlineIcon: InlineIcon$2}=perseus.components;class HintEditor extends React__namespace.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-hint-editor "+this.props.className,children:[this.props.showTitle&&jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Hint"}),jsxRuntimeExports.jsx(Editor,{ref:this.editor,apiOptions:this.props.apiOptions,widgets:this.props.widgets||undefined,content:this.props.content||undefined,images:this.props.images,replace:this.props.replace,placeholder:"Type your hint here...",imageUploader:this.props.imageUploader,onChange:this.props.onChange,widgetIsOpen:this.props.widgetIsOpen},this.props.itemId),jsxRuntimeExports.jsxs("div",{className:"hint-controls-container clearfix",children:[this.props.showMoveButtons&&jsxRuntimeExports.jsxs("span",{className:"reorder-hints",children:[jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isLast?"hidden":"",onClick:___default.default.partial(this.props.onMove,1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowDown})})," ",jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isFirst?"hidden":"",onClick:___default.default.partial(this.props.onMove,-1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowUp})})," ",this.props.isLast&&jsxRuntimeExports.jsx(InfoTip$q,{children:jsxRuntimeExports.jsx("p",{children:"The last hint is automatically bolded."})})]}),jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.replace,onChange:this.handleChange}),"Replace previous hint",this.props.showRemoveButton&&jsxRuntimeExports.jsxs("button",{type:"button",className:"remove-hint simple-button orange",onClick:this.props.onRemove,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...perseus.iconTrash}),"Remove this hint"," "]})]})]})}constructor(...args){super(...args),this.editor=React__namespace.createRef(),this.handleChange=e=>{this.props.onChange({replace:e.target.checked});},this.focus=()=>{this.editor.current?.focus();},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.serialize=options=>{return this.editor.current?.serialize(options)};}}HintEditor.defaultProps={className:"",content:"",replace:false,showMoveButtons:true,showTitle:true,showRemoveButton:true};class CombinedHintEditor extends React__namespace.Component{componentDidMount(){this.updatePreview();}componentDidUpdate(){this.updatePreview();}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";return jsxRuntimeExports.jsxs("div",{className:"perseus-combined-hint-editor "+"perseus-editor-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(HintEditor,{ref:this.editor,itemId:this.props.itemId,isFirst:this.props.isFirst,isLast:this.props.isLast,widgets:this.props.hint.widgets,content:this.props.hint.content,images:this.props.hint.images,replace:this.props.hint.replace,imageUploader:this.props.imageUploader,onChange:this.props.onChange,onRemove:this.props.onRemove,onMove:this.props.onMove,apiOptions:this.props.apiOptions,widgetIsOpen:this.props.widgetIsOpen})}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.deviceType,nochrome:true,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:this.frame,datasetKey:"mobile",datasetValue:isMobile,seamless:true,url:this.props.previewURL})})})]})}constructor(...args){super(...args),this.editor=React__namespace.createRef(),this.frame=React__namespace.createRef(),this.updatePreview=()=>{const shouldBold=this.props.isLast&&!/\*\*/.test(this.props.hint.content);this.frame.current?.sendNewData({type:"hint",data:{hint:this.props.hint,bold:shouldBold,pos:this.props.pos,apiOptions:this.props.apiOptions,linterContext:{contentType:"hint",highlightLint:this.props.highlightLint,paths:this.props.contentPaths}}});},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.serialize=options=>{return this.editor.current?.serialize(options)},this.focus=()=>{this.editor.current?.focus();};}}CombinedHintEditor.defaultProps={highlightLint:false};class CombinedHintsEditor extends React__namespace.Component{render(){const{itemId,hints}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const hintElems=___default.default.map(hints,function(hint,i){return jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(CombinedHintEditor,{ref:"hintEditor"+i,isFirst:i===0,isLast:i+1===hints.length,itemId:itemId,hint:hint,pos:i,imageUploader:this.props.imageUploader,onChange:this.handleHintChange.bind(this,i),onRemove:this.handleHintRemove.bind(this,i),onMove:this.handleHintMove.bind(this,i),deviceType:this.props.deviceType,apiOptions:this.props.apiOptions,highlightLint:this.props.highlightLint,previewURL:this.props.previewURL,contentPaths:[],widgetIsOpen:this.props.widgetIsOpen})},"hintEditor"+i)},this);return jsxRuntimeExports.jsxs("div",{className:"perseus-hints-editor perseus-editor-table",children:[hintElems,jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"add-hint-container perseus-editor-left-cell",children:jsxRuntimeExports.jsxs("button",{type:"button",className:"add-hint simple-button orange",disabled:editingDisabled,onClick:this.addHint,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconPlus})," Add a hint"]})})})]})}constructor(...args){super(...args),this.handleHintChange=(i,newProps,cb,silent)=>{const hints=[...this.props.hints];hints[i]=___default.default.extend({},this.serializeHint(i,{keepDeletedWidgets:true}),newProps);this.props.onChange({hints:hints},cb,silent);},this.handleHintRemove=i=>{if(!confirm("Are you sure you want to delete this hint?")){return}const hints=[...this.props.hints];hints.splice(i,1);this.props.onChange({hints:hints});},this.handleHintMove=(i,dir)=>{const hints=[...this.props.hints];const hint=hints.splice(i,1)[0];hints.splice(i+dir,0,hint);this.props.onChange({hints:hints},()=>{this.refs["hintEditor"+(i+dir)].focus();});},this.addHint=()=>{const hint={content:"",images:{},widgets:{}};const hints=[...this.props.hints,hint];this.props.onChange({hints:hints},()=>{const i=hints.length-1;this.refs["hintEditor"+i].focus();});},this.getSaveWarnings=()=>{return ___default.default.chain(this.props.hints).map((hint,i)=>{return ___default.default.map(this.refs["hintEditor"+i].getSaveWarnings(),issue=>"Hint "+(i+1)+": "+issue)}).flatten(true).value()},this.serialize=options=>{return this.props.hints.map((hint,i)=>{return this.serializeHint(i,options)})},this.serializeHint=(index,options)=>{return this.refs["hintEditor"+index].serialize(options)};}}CombinedHintsEditor.HintEditor=HintEditor;CombinedHintsEditor.defaultProps={onChange:()=>{},hints:[],highlightLint:false};
|
|
1528
1528
|
|
|
1529
1529
|
const IMAGE_MARKDOWN_REGEX=/!\[[^\]]*\]\([^)]+\)/g;function getFirstAvailableWidgetIndex(widgetType,widgets){const widgetNames=Object.keys(widgets);for(let i=1;i<=widgetNames.length+1;i++){if(!widgetNames.includes(`${widgetType} ${i}`)){return i}}return 1}async function convertImageMarkdownToImageWidget(question,onEditorChange){const{content,widgets}=question;const newWidgets={...widgets};const matches=Array.from(content.matchAll(IMAGE_MARKDOWN_REGEX));if(matches.length===0){return}const replacements=[];for(const match of matches){const imageIndex=getFirstAvailableWidgetIndex("image",newWidgets);const imageNode=perseus.PerseusMarkdown.parse(match[0],{});const imageUrl=imageNode[0].content[0].target;const imageAlt=imageNode[0].content[0].alt;const imageSize=await perseus.Util.getImageSizeModern(imageUrl);const[width,height]=imageSize;newWidgets[`image ${imageIndex}`]=perseusCore.generateImageWidget({options:perseusCore.generateImageOptions({backgroundImage:{url:imageUrl,width,height},alt:imageAlt})});replacements.push({original:match[0],replacement:`[[☃ image ${imageIndex}]]`});}let newContent=content;for(const{original,replacement}of replacements){newContent=newContent.replace(original,replacement);}onEditorChange({content:newContent,widgets:newWidgets});}function getCtaForIssueId(issueId,question,onEditorChange){switch(issueId){case "image-markdown":return {label:"Convert all image markdown to widget",onClick:()=>convertImageMarkdownToImageWidget(question,onEditorChange)};default:return null}}
|
|
1530
1530
|
|