diff --git a/packages/learn/src/templates/Challenges/classic/Show.js b/packages/learn/src/templates/Challenges/classic/Show.js index 6c7fe25db0d..bcfc57edbdf 100644 --- a/packages/learn/src/templates/Challenges/classic/Show.js +++ b/packages/learn/src/templates/Challenges/classic/Show.js @@ -32,6 +32,8 @@ import { import './classic.css'; +import decodeHTMLEntities from '../../../../utils/decodeHTMLEntities'; + const mapStateToProps = createSelector( challengeFilesSelector, challengeTestsSelector, @@ -200,7 +202,7 @@ class ShowClassic extends PureComponent { * Your test output will go here. */ `} - output={output} + output={decodeHTMLEntities(output)} /> ) : null} diff --git a/packages/learn/utils/decodeHTMLEntities.js b/packages/learn/utils/decodeHTMLEntities.js new file mode 100644 index 00000000000..aa29d9f9260 --- /dev/null +++ b/packages/learn/utils/decodeHTMLEntities.js @@ -0,0 +1,27 @@ +/* + * Converts HTML entity codes in a string to the characters they represent. + * + * Example: + * `decodeHTMLEntities('Beets & carrots');` + * will return "Beets & carrots". + * + * The regex makes sure we only replace the HTML entities in the string. + * For example, the regex would match "<" as well as ":". + * The decoding works by setting the innerHTML of a dummy element and then + * retrieving the innerText. Per the spec, innerText is a property that + * represents the "rendered" text content of an element. + * + * See: + * https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText + * https://developer.mozilla.org/en-US/docs/Glossary/Entity + * + */ +const decodeHTMLEntities = str => { + const el = document.createElement('div'); + return str.replace(/\&[#0-9a-z]+;/gi, enc => { + el.innerHTML = enc; + return el.innerText; + }); +}; + +export default decodeHTMLEntities;