Skip to content

Commit

Permalink
Merge pull request #623 from digabi/feature/save-answer-on-equation-c…
Browse files Browse the repository at this point in the history
…hange

Save answer on equation change
  • Loading branch information
heeboA authored Dec 3, 2024
2 parents d95573f + fe2ef43 commit a2238a1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
41 changes: 40 additions & 1 deletion playwright/editor.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,45 @@ test.describe('Rich text editor', () => {
})
})

test('updates the answer when equation is changed', async ({ page }) => {
await page.keyboard.press('1')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('1') })
await page.keyboard.press('2')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('12') })

await test.step('updates on undo', async () => {
await page.keyboard.press('Control+z')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('1') })
})

await test.step('updates with long text', async () => {
await page.keyboard.type('testing that this works when there is a lot of text as well')
assertAnswerContent(answer, {
answerHtml: getLatexImgTag(
'1testing\\ that\\ this\\ works\\ when\\ there\\ is\\ a\\ lot\\ of\\ text\\ as\\ well',
),
})
await selectAll(page)
await page.keyboard.press('Backspace')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('') })
})

await test.step('updates when latex command is inserted', async () => {
await inputLatexCommandFromToolbar(page, specialCharacters.sqrt[0])
assertAnswerContent(answer, { answerHtml: getLatexImgTag('\\sqrt{ }') })
await page.keyboard.type('123')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('\\sqrt{123}') })
})

await test.step('updates when re-opnening an equation', async () => {
await page.keyboard.press('Escape')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('\\sqrt{123}') })
await getEditorLocator(page).getByRole('img').first().click()
await page.keyboard.type('abc')
assertAnswerContent(answer, { answerHtml: getLatexImgTag('\\sqrt{123}abc') })
})
})

test.describe('when multiple equation editors in answer', () => {
test.beforeEach(async ({ page }) => {
await page.keyboard.press('A')
Expand Down Expand Up @@ -677,7 +716,7 @@ test.describe('Rich text editor', () => {
test('after editor with Tab in Latex field', async ({ page }) => {
await expect(page.getByRole('img').last()).toBeVisible()
await page.getByRole('img').last().click()
// first TAb to focus latex-field
// first Tab to focus latex-field
await page.keyboard.press('Tab')
await page.keyboard.press('Tab')
await page.keyboard.type('XX')
Expand Down
13 changes: 7 additions & 6 deletions src/app/state/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export function EditorStateProvider({

function onChange(latex: string) {
equationEditorHistory.write(latex)
onAnswerChange(false, false)
}

function onEnter(latex: string) {
Expand Down Expand Up @@ -276,12 +277,6 @@ export function EditorStateProvider({
* @param shouldUpdateHistoryImmediately - Whether to update the answer history immediately, without debouncing (defaults to false)
*/
function onAnswerChange(shouldUpdateHistory: boolean = true, shouldUpdateHistoryImmediately: boolean = false) {
/** This 0ms timeout is crucial - it essentially moves the callback into the next event loop,
* after pending DOM changes have been made in the current loop (in practice,
* this is needed because closing a math editor changes the HTML of the answer,
* but doesn't trigger the text area's onInput event. With this hack we can get the answer HTML with
* the changes already included.)
*/
const fn = () => {
const content = mainTextAreaRef.current?.innerHTML
if (content !== undefined) {
Expand All @@ -297,6 +292,12 @@ export function EditorStateProvider({
}
}
}
/** This 0ms timeout is crucial - it essentially moves the callback into the next event loop,
* after pending DOM changes have been made in the current loop (in practice,
* this is needed because closing a math editor changes the HTML of the answer,
* but doesn't trigger the text area's onInput event. With this hack we can get the answer HTML with
* the changes already included.)
*/
setTimeout(fn, 0)
}

Expand Down
3 changes: 1 addition & 2 deletions src/app/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ export const getAnswer = (html: string) => {
transformTags: {
img: (tagName: string, attribs: Attributes) =>
attribs.src ? { tagName, attribs } : { tagName: '', attribs: {} },
span: (tagName: string, attribs: Attributes) =>
attribs.class !== MATH_EDITOR_CLASS ? { tagName, attribs } : { tagName: '', attribs: {} },
},
exclusiveFilter: (frame) => frame.tag === 'span' && frame.attribs?.class === MATH_EDITOR_CLASS,
})
const answer = new DOMParser().parseFromString(answerHtml, 'text/html').body
const answerText = Array.from(answer.childNodes)
Expand Down

0 comments on commit a2238a1

Please sign in to comment.