How can I implement support for resuming in an H5P content type?

Implementing H5P’s resume (or “save content state”) feature is pretty simple for developers. Whenever the core of H5P wants to store the current state of a content type instance, it will try to call a function named getCurrentState and expects the function to return anything that you might want to store.

When the user opens some H5P content and should resume, then H5P core will pass the previous state as a property of the constructor’s third argument. You will receive what you stored and can use that information to restore the state as you need it in your content type.

So, in order to make sure that your state data can be saved, you only need to make sure that there is an exposed function named appropriately that does exactly that. For instance:

 * Answer H5P core call to return the current state.
 * @returns {object} Current state.
getCurrentState() {
  return {
    answersChecked: [1, 2, 3, 5, 8, 13, 21],
    somethingNested: {
      foo: 'FOO',
      bar: 'BAR'
    somethingElse: true

In practice, while you could return anything, you should always return an object even though you currently may only need one single number or maybe an array. You may not need to store much now, but if you ever do later on as your content type evolves, you would need to add extra code to distinguish whether the previous state that you will receive still is a boolean / number / "array" / string or already an object.

 * @class
 * @param {object} params Parameters passed by the editor.
 * @param {number} contentId Content's id.
 * @param {object} [extras={}] Saved state, metadata, etc.
constructor(params, contentId, extras = {}) {
   * `extras.previousState` should either be nullish if there is
   * no previous state that needs to be re-created or it
   * will be the return value of your `getCurrentState` function.

How do I add support to compound content types?

If you ever create a compound content type that holds H5P subcontents, your compound content type can collect all the subcontents’ states by calling their getCurrentState function (if they have one) and pass the returned values (or undefined) as part of the compound content type’s state. H5P core does not communicate with the subcontents directly. You will need to fill that gap.

The other way round, when you receive the previous state when instantiating your compound content type, you need to send the subcontens’ previous states to the right recipients. Normally, the newRunnable function of H5P core is used to instantiate subcontent. That function expects a previousState property inside the 5th argument. Its value needs to be the state information that you received from getCurrentState like so:

const subcontentInstance = H5P.newRunnable(
  { previousState: { ... } }