mathlive icon indicating copy to clipboard operation
mathlive copied to clipboard

Macros not available at MFE instantiation

Open AllyMarthaJ opened this issue 1 year ago • 10 comments

Description

Macros are not available at MathfieldElement instantiation.

This means that if creating a MathfieldElement programmatically and injecting it into the page at a later time, we erase any pre-existing macros.

Steps to Reproduce

Minimal, reproducible example:

import { MathfieldElement } from "mathlive"; // Using something like webpack

function createMfe() {
    const mf = MathfieldElement();
    mf.macros = { ...mf.macros, sf: { args: 1, def: "\\mathsf{#1}", captureSelection: false } };
}

document.body.appendChild(createMfe());

Codepen: https://codepen.io/ladyally/pen/NWmLmro

I can get around this by deferring macro setting to the next frame.

Work around: https://codepen.io/ladyally/pen/VwNGNKr

Actual Behavior

Observe that macros such as \imaginaryI does not work, but \sf{x} does (for example).

Expected Behavior

I would expect pre-existing macros to be loaded before assigning new ones. Or, at the very least, being able to set macros at instantiation in addition to any ones which will be loaded further on.

Environment

Is this a regression: did it use to work in a previous version?

MathLive version : 0.95.0. Replicable on latest mathlive (per the codepen!).

Operating System macOS 13.2.1

Browser Chrome

AllyMarthaJ avatar Apr 17 '24 06:04 AllyMarthaJ

That's an interesting issue. Before the element is attached to the DOM, there are some limitations, and this is currently one of them. See the description of the lifecycle: https://cortexjs.io/mathlive/guides/lifecycle/

In general, the recommendation is to listen for the mount event and do the customization of the mathfield from within that event handler.

I'll try to see if this can be improved...

arnog avatar Apr 17 '24 14:04 arnog

Ahhh right, okay! That makes sense; most of the examples in the documentation sort of depend on that implicitly I suppose.

AllyMarthaJ avatar Apr 17 '24 21:04 AllyMarthaJ

Yes, the examples in the doc have been carefully chosen. Before the component is mounted, if some properties are modified, they are stored aside, then reapplied when the component is finally mounted. This doesn’t work for properties like macros that require being able to read the current value as well.

Maybe it would be better to just throw if any properties are read or modified. before the component is mounted and require those changes to be made in the mount handler?

arnog avatar Apr 17 '24 22:04 arnog

Maybe it would be better to just throw if any properties are read or modified. before the component is mounted and require those changes to be made in the mount handler?

Yup, I think that works. Either way it's good to know 🙂

AllyMarthaJ avatar Apr 17 '24 23:04 AllyMarthaJ

Noting something else I discovered for posterity: a bug wherein if you set the content of the mathfield before it's mounted, and then instantiate the config on mount then some weird stuff with braces occurs. At a glance: set the content to \placeholder, configure on mount, and then typing ( will insert ()( instead. e.g. image

Not that it's a problem, because setting the content after it's mounted also fixes the issue. So...that was fun.

AllyMarthaJ avatar Jun 11 '24 11:06 AllyMarthaJ

@AllyMarthaJ maybe it doesn't matter much, but I've tried to reproduce this issue and have not had much luck. You wouldn't happen to have a CodePen that illustrates the problem?

arnog avatar Jun 11 '24 17:06 arnog

@arnog I've got one for you here: https://codepen.io/ladyally/pen/wvbrxmN

What I realised when coming up with this example is that there's an additional call to focus. Without the call to focus, this doesn't occur. My bad, sorry!

Just for posterity I added a delay so it's easier to focus on the codepen iframe before the mathfield loads. It's not necessary to repro the bug.

AllyMarthaJ avatar Jun 11 '24 21:06 AllyMarthaJ

I would like to pitch in on this issue as well. We ran into this problem when upgrading from 0.98.6. I can make a new issue, but i think this is related to the same underlying cause.

We do the following:

  • create a new mathfield (object)
  • set initial value
  • set macros
  • add mathfield to dom

This worked fine up to version 0.98.6. However, from version 0.99.0 on (and thus also in 0.100.0) we have the following issue:

  • when the macros are set before adding the mathfield to the dom (so before the "mount" event), an error is thrown "Error: Mathfield not mounted"
  • this now requires to set the macro after mounting, causing the issue that if the value set before mounting has macros in them, they will be temporarily rendered as "invalid" latex (since the macros are not defined).
  • after mounting and updating the macros the value is shown including the macros.

Since this is a regression from the previous version I would like to see if we can fix this and allow again to set macros before adding anything to the dom. This allows for configuring the mathfield before allowing a user to interact instead of having to wait for it to be available in the DOM.

To show this I've created the following three CodePens:

  • Version 0.98.6: able to set macros before adding to DOM -> https://codepen.io/thijsgrasple/pen/rNgXmVb
  • Version 0.100.0 (latest at this moment): not able to set the macros before adding to DOM (see console error): https://codepen.io/thijsgrasple/pen/KKLOmpB
  • Version 0.100.0 (latest at this moment): showing issue of setting macros after mount by delaying the update of setting the macros: https://codepen.io/thijsgrasple/pen/xxNvqvv

In addition, a separate issue arises in version 0.100.0 when having to set the macros after the mathfield has been added to the DOM: it causes focus on the (last) mathfield. See this new issue regarding that problem: https://github.com/arnog/mathlive/issues/2427

screambeard avatar Jul 02 '24 12:07 screambeard

@screambeard Thanks for the detailed report. I think the issue of updating after mount and the mathfield not refreshing is fixed in the unreleased version, but I'll double-check.

The issue with setting macros before mount is that the default macros are not available at that time. So you can override the macros, but you can't add to them.

Changing lifecycle so that macros can be modified (and read) before mount is not trivial, but I'll look into it.

arnog avatar Jul 02 '24 22:07 arnog

@arnog thanks for the explanation. The only thing I'm a bit confused by is why this changed from 0.98.6 to 0.99.0? Because we were able to add macros before mounting in version 0.98.6.

I think the key blocker for upgrading for us at this moment is the other issue regarding the focus on mathfield when updating the macros: https://github.com/arnog/mathlive/issues/2427.

Let me know if I can help you with anything.

screambeard avatar Jul 03 '24 06:07 screambeard