Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Input Numbers in Explanation Widgets #1900

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions .changeset/curly-trains-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/perseus": patch
---

Bugfix for explantion widgets after Input Number Conversion
29 changes: 24 additions & 5 deletions packages/perseus/src/util/deprecated-widgets/input-number.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Methods to convert input-number widgets to numeric-input widgets
import type {PerseusExplanationWidgetOptions} from "../../perseus-types";
import type {
NumericInputWidget,
PerseusRenderer,
Expand All @@ -15,6 +16,11 @@ export const inputNumberToNumericInput = (json: PerseusRenderer) => {
// so that we can ensure we update the content and widgets accordingly
const renameMap = getInputNumberRenameMap(json);

// If there are no input-number widgets, we can return the json as is
if (renameMap === null) {
return json;
}

// Then we can use this to update the JSON
return convertInputNumberJson(json, renameMap);
};
Expand Down Expand Up @@ -112,24 +118,31 @@ export const convertInputNumberWidgetOptions = (
// Convert the deprecated widget refs in the content string
// of a PerseusRenderer object to their renamed equivalents
const convertDeprecatedWidgetsInContent = (
json: PerseusRenderer,
json: PerseusRenderer | PerseusExplanationWidgetOptions,
renameMap: WidgetRenameMap,
): string => {
const contentString = "content" in json ? json.content : json.explanation;
return Object.keys(renameMap).reduce((newContent, oldKey) => {
const newKey = renameMap[oldKey];
return newKey ? newContent.replace(oldKey, newKey) : newContent;
}, json.content);
}, contentString);
};

// Create a map of the old input-number keys to the new numeric-input keys
export const getInputNumberRenameMap = (
json: PerseusRenderer,
): WidgetRenameMap => {
json: PerseusRenderer | PerseusExplanationWidgetOptions,
): WidgetRenameMap | null => {
const numericRegex = /(?<=\[\[\u2603 )(numeric-input \d+)(?=\]\])/g;
const inputNumberRegex = /(?<=\[\[\u2603 )(input-number \d+)(?=\]\])/g;

// Get all the content strings within the json, which might be nested within widgets
const allContentStrings = json.content;
const allContentStrings =
"content" in json ? json.content : json.explanation || "";

// If there are no content strings, we can return null
if (allContentStrings === "") {
return null;
}

// Loop through the content strings to get all the input-number widgets
const renameMap: WidgetRenameMap = {};
Expand Down Expand Up @@ -184,6 +197,12 @@ export const convertInputNumberForScoring = (
// First we need to create a map of the old input-number keys to the new numeric-input keys
// so that we can ensure we update the content, widgets, AND userInput accordingly
const renameMap = getInputNumberRenameMap(rubric);

// If there are no input-number widgets, we can return the json as is
if (renameMap === null) {
return {convertedRubric: rubric, convertedUserData: userInputMap};
}

const convertedRubric = convertInputNumberJson(rubric, renameMap);
const convertedUserData = convertUserInputNumberData(
userInputMap,
Expand Down