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

Use an intermediate exam format in rendering code #45

Open
sluukkonen opened this issue Dec 4, 2019 · 3 comments
Open

Use an intermediate exam format in rendering code #45

sluukkonen opened this issue Dec 4, 2019 · 3 comments
Labels
enhancement New feature or request

Comments

@sluukkonen
Copy link
Contributor

sluukkonen commented Dec 4, 2019

Right now we use DOMParser for parsing the mastered exam XML and interpret the document with the help of the regular DOM API. While it is has been quite convenient from a development standpoint, since we have been able to use the full power of the DOM API for free, there are some downsides:

  • Rendering an exam to HTML on the server is impossible, since it requires JSDOM and the JSDOM implementation isn't quite up to snuff. Particularly, the JSDOM implementation of querySelectorAll does not seem to work at all with namespaced XML elements.
  • Rendering tests are slow, since we need to fire up a webpack-dev-server and use a real browser to execute the rendering code.
  • XML attributes are stringly-typed.
  • Offline exam rendering requires JavaScript to show anything but a blank page

As an alternative, we could translate the XML document to a JSON format, which would contain Elements and Nodes just like a regular XML document. That is, it would be isomorphic to real XML.

This would have a few upsides:

  • We could render the exam to HTML with Node.js, since the rendering code wouldn’t be reliant on DOMParser and the DOM API.
  • Offline exam HTML files could contain the pre-rendered "server-side" React-generated HTML for faster initial rendering and less reliance in JS in general.
  • The attributes of elements could contain all JSON data types, not just strings.
  • Rendering tests could be performed without starting a webpack server and a browser (i.e. they could be lightning fast).
  • We could define TypeScript typings for the attributes of each exam element type. This would make the code more approachable, since one wouldn’t have to know that a particular exam element contains so-and-so attributes, the attributes of each element would be encoded directly in TypeScript types. We also wouldn’t have to coerce the attributes to the correct type everywhere.

The downside (apart from the work required) is that we would have to reinvent the wheel in some respects. We would have to implement our own functions for operations like “get the closest parent element like this” (Element.closest) and “query for elements like these in this subtree” (Element.querySelectorAll).

@sluukkonen
Copy link
Contributor Author

This will partly be solved by #60. We still use DOM API's in rendering, but afterwards it will run with JSDOM.

@sluukkonen sluukkonen added the enhancement New feature or request label Dec 17, 2019
@sluukkonen
Copy link
Contributor Author

sluukkonen commented Feb 8, 2021

As an alternative or an intermediate solution, we could just add dedicated parser functions for each element type. This way each component wouldn't have to parse the attributes manually.

As an example

function ExamQuestion({ element }: ExamComponentProps) {
  const { displayNumber, maxScore } = parseQuestionAttributes(element)
  
}

where parseQuestionAttributes would be a function like (question: Element) => { displayNumber: string, maxScore?: number }. Each component could the destructure the result and use the values that they need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant