Web Component Lifecycle

A mathfield web component goes through various stages during its lifecycle.

In most cases, this is something you don’t have to pay much attention to. Just remember these guidelines:

  • Once a component is attached to the DOM attributes (key/value pairs attached to the <math-field> tag and properties (key/value pairs attached to a MathfieldElement object) are kept in sync, or reflected. You can also call the methods of MathfieldElement without limitations. You can be notified of this state by listening for a mount event on the element.
  • Before the component is attached to the DOM or even before the MathfieldElement class has been registered, you can still interact with the element, but with some limitations. The value, selection, options and disabled properties and related attributes are safe to set, but the values you read back may be different than once the component is mounted.

Initialization

The element has been created from markup, but the code registering the <math-field> tag with the MathfieldElement class has not been executed yet. This could happen if the scripts are loaded in an unexpected order or if there is a temporary networking issue.

At this stage:

  • you can read and change the disabled, value, options, selection and position properties on the element.
document.querySelector('math-field').value = '\\sin x';

However, some of those properties behave in limited way. For example, the options property usually return the default value for the options. However, at this stage, it will only return the values you have set.

  • you can change/add/remove attributes on the element. At this stage, the attributes and the properties are independent, so if you set for example the virtual-keyboard-mode attribute, it will not be reflected in `options.virtualKeyboardMode.
  • the only methods on the element that can be invoked are those of HTMLElement since the element has not been upgraded yet.

To be notified when the registration takes place, use the whenDefined() method.

customElements.whenDefined('math-field').then(() => {
  console.log('<math-field> is defined');
});

If all goes well, the element will be constructed next.

Constructed

This stage occurs either after the previous one (i.e. an element created from markup) or when an element is created programmatically with new MathfieldElement().

The HTMLElement object exist, but it is not yet attached to the DOM. You can interact with the object, but its operations are limited.

At this stage:

  • you can read and change the properties as before. However, doing so will be reflected on attributes as well. That is calling mf.setOptions({ virtualKeyboardMode: "manual"}) will result in mf.getAttribute('virtual-keyboard-mode') to return "manual".
  • you can read and change the attributes as before, however they will now be reflected on properties as well, that is calling mf.setAttribute('virtual-keyboard-mode', 'manual') will result in mf.getOption('virtualKeyboardMode') to return "manual".
  • you can change/add/remove attributes on the element
  • you can invoke all methods specific to MathfieldElement, however some may have some limitations. For example setValue() will ignore any options provided including formats other than Latex, executeCommand() will do nothing, etc… These commands required the element to be attached to the DOM to function properly.

Attached/Mounted

This stage occurs after the previous one. The transition to this stage happens automatically for elements created from markup after the MathfieldElement class has been registered to handle the <math-field> tag. If the element was created programatically, this stage is reached when the element is explicitly attached to the DOM, for example using appendChild().

At this stage:

  • you can read and change properties and attributes and they will reflect each other (changing an attribute will update the corresponding property and vice versa).
  • you can invoke all properties of MathfieldElement without limitations

To be notified when this stage is reached, listen for the mount event on the element:

md.addEventListener('mount')((ev) => {
  console.log('mf is mounted');
  // You can now read default options value for example, or 
  //call `setValue()` with format options other than Latex.
  console.log(ev.target.getOption('macros'));
});

Detached/Unmounted

This stage can be reached if the element is explicitly removed from the DOM, for example with ChildNode.remove().

This stage is not reached when the page is closed: in that case the element is immediately disposed of.

Once this stage is reached, the same limitations as in the Constructed stage apply.

Note that the next stage could be either for element to be disposed of or to be re-attached.

To be notified when this stage is reached, listen for the unmount event on the element:

md.addEventListener('unmount')((ev) => {
  console.log('mf is about to be unmounted');
  // Last change to interact with the mathfield
  console.log(ev.target.getValue('ASCIIMath'));
});

Next

Customizing a mathfield
How to customize the behavior and appearance of a mathfield.