math-ml icon indicating copy to clipboard operation
math-ml copied to clipboard

Hidden math-ml does not recalculate width

Open tirithen opened this issue 5 years ago • 1 comments

When I try to use the math-ml component in a tooltip that starts as hidden the component calculates the wrong width (maybe the width of math-frac?), I'm trying to find a way to externally trigger a re-render, no luck so far but might be possible. Regardless it would be good to somehow watch for display state of a parents and re-render/calculate width when needed automatically.

See animation and matching example code. The end result in the two tooltips are different because one of them starts with display: none.

hidden-math-ml-does-not-recalculate-width

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <style>
      .tooltip {
        position: absolute;
        top: 5vw;
        left: 5vw;
      }

      .tooltip:last-of-type {
        left: auto;
        right: 5vw;
      }

      .tooltip__container {
        max-width: calc(85vw / 2);
        background: #fff;
        border: 1px solid #000;
        padding: 1rem;
        border-radius: 0.5rem;
        box-sizing: border-box;
        overflow: auto;
      }

      .mathml-container {
        overflow: auto;
      }
    </style>

    <h1>Static position</h1>
    <div class="mathml-container">
      <math-ml display="block">
        <math-frac>
          <math-n>1</math-n>
          <math-row>
            <math-n>1</math-n>
            <math-o>+</math-o>
            <math-sup>
              <math-i>e</math-i>
              <math-row>
                <math-o>-</math-o>
                <math-row>
                  <math-o>(</math-o>
                  <math-n>1.713</math-n>
                  <math-i>E</math-i>
                  <math-o>+</math-o>
                  <math-n>0.847</math-n>
                  <math-i>A</math-i>
                  <math-o>+</math-o>
                  <math-n>0.607</math-n>
                  <math-i>R</math-i>
                  <math-o>+</math-o>
                  <math-n>1.417</math-n>
                  <math-i>V</math-i>
                  <math-o>+</math-o>
                  <math-n>2.058</math-n>
                  <math-i>S</math-i>
                  <math-o>+</math-o>
                  <math-n>1.208</math-n>
                  <math-i>H</math-i>
                  <math-o>+</math-o>
                  <math-n>0.089</math-n>
                  <math-i>T</math-i>
                  <math-o>-</math-o>
                  <math-n>4.766</math-n>
                  <math-o>)</math-o>
                </math-row>
              </math-row>
            </math-sup>
          </math-row>
        </math-frac>
      </math-ml>
    </div>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    <div class="tooltip" style="display: none;">
      <div class="tooltip__container">
        <h1>Open on click</h1>
        <div class="mathml-container">
          <math-ml display="block">
            <math-frac>
              <math-n>1</math-n>
              <math-row>
                <math-n>1</math-n>
                <math-o>+</math-o>
                <math-sup>
                  <math-i>e</math-i>
                  <math-row>
                    <math-o>-</math-o>
                    <math-row>
                      <math-o>(</math-o>
                      <math-n>1.713</math-n>
                      <math-i>E</math-i>
                      <math-o>+</math-o>
                      <math-n>0.847</math-n>
                      <math-i>A</math-i>
                      <math-o>+</math-o>
                      <math-n>0.607</math-n>
                      <math-i>R</math-i>
                      <math-o>+</math-o>
                      <math-n>1.417</math-n>
                      <math-i>V</math-i>
                      <math-o>+</math-o>
                      <math-n>2.058</math-n>
                      <math-i>S</math-i>
                      <math-o>+</math-o>
                      <math-n>1.208</math-n>
                      <math-i>H</math-i>
                      <math-o>+</math-o>
                      <math-n>0.089</math-n>
                      <math-i>T</math-i>
                      <math-o>-</math-o>
                      <math-n>4.766</math-n>
                      <math-o>)</math-o>
                    </math-row>
                  </math-row>
                </math-sup>
              </math-row>
            </math-frac>
          </math-ml>
        </div>
        <p>Lorem ipsum dolor sit amet.</p>
      </div>
    </div>

    <button>Open tooltip</button>

    <script>
      const button = document.querySelector('button');
      const tooltip = document.querySelector('.tooltip');

      button.addEventListener('click', () => {
        tooltip.style.display = 'block';
      });
    </script>

    <div class="tooltip">
      <div class="tooltip__container">
        <h1>Always visible</h1>
        <div class="mathml-container">
          <math-ml display="block">
            <math-frac>
              <math-n>1</math-n>
              <math-row>
                <math-n>1</math-n>
                <math-o>+</math-o>
                <math-sup>
                  <math-i>e</math-i>
                  <math-row>
                    <math-o>-</math-o>
                    <math-row>
                      <math-o>(</math-o>
                      <math-n>1.713</math-n>
                      <math-i>E</math-i>
                      <math-o>+</math-o>
                      <math-n>0.847</math-n>
                      <math-i>A</math-i>
                      <math-o>+</math-o>
                      <math-n>0.607</math-n>
                      <math-i>R</math-i>
                      <math-o>+</math-o>
                      <math-n>1.417</math-n>
                      <math-i>V</math-i>
                      <math-o>+</math-o>
                      <math-n>2.058</math-n>
                      <math-i>S</math-i>
                      <math-o>+</math-o>
                      <math-n>1.208</math-n>
                      <math-i>H</math-i>
                      <math-o>+</math-o>
                      <math-n>0.089</math-n>
                      <math-i>T</math-i>
                      <math-o>-</math-o>
                      <math-n>4.766</math-n>
                      <math-o>)</math-o>
                    </math-row>
                  </math-row>
                </math-sup>
              </math-row>
            </math-frac>
          </math-ml>
        </div>
        <p>Lorem ipsum dolor sit amet.</p>
      </div>
    </div>

    <script src="https://unpkg.com/mathml-elements@latest/dist/bundled/mathml.min.js"></script>
  </body>
</html>

tirithen avatar Apr 27 '20 16:04 tirithen

I have a workaround for now by saving the original definitions and setting the innerHTML again with a mutation observer, it's probably slow but it gets the job done. It would still be nice to have them auto resize in a good way.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <style>
      .tooltip {
        position: absolute;
        top: 5vw;
        left: 5vw;
      }

      .tooltip:last-of-type {
        left: auto;
        right: 5vw;
      }

      .tooltip__container {
        max-width: calc(85vw / 2);
        background: #fff;
        border: 1px solid #000;
        padding: 1rem;
        border-radius: 0.5rem;
        box-sizing: border-box;
        overflow: auto;
      }

      .mathml-container {
        overflow: auto;
      }
    </style>

    <h1>Static position</h1>
    <div class="mathml-container">
      <math-ml display="block">
        <math-frac>
          <math-n>1</math-n>
          <math-row>
            <math-n>1</math-n>
            <math-o>+</math-o>
            <math-sup>
              <math-i>e</math-i>
              <math-row>
                <math-o>-</math-o>
                <math-row>
                  <math-o>(</math-o>
                  <math-n>1.713</math-n>
                  <math-i>E</math-i>
                  <math-o>+</math-o>
                  <math-n>0.847</math-n>
                  <math-i>A</math-i>
                  <math-o>+</math-o>
                  <math-n>0.607</math-n>
                  <math-i>R</math-i>
                  <math-o>+</math-o>
                  <math-n>1.417</math-n>
                  <math-i>V</math-i>
                  <math-o>+</math-o>
                  <math-n>2.058</math-n>
                  <math-i>S</math-i>
                  <math-o>+</math-o>
                  <math-n>1.208</math-n>
                  <math-i>H</math-i>
                  <math-o>+</math-o>
                  <math-n>0.089</math-n>
                  <math-i>T</math-i>
                  <math-o>-</math-o>
                  <math-n>4.766</math-n>
                  <math-o>)</math-o>
                </math-row>
              </math-row>
            </math-sup>
          </math-row>
        </math-frac>
      </math-ml>
    </div>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    <div class="tooltip" style="display: none;">
      <div class="tooltip__container">
        <h1>Open on click</h1>
        <div class="mathml-container">
          <math-ml display="block">
            <math-frac>
              <math-n>1</math-n>
              <math-row>
                <math-n>1</math-n>
                <math-o>+</math-o>
                <math-sup>
                  <math-i>e</math-i>
                  <math-row>
                    <math-o>-</math-o>
                    <math-row>
                      <math-o>(</math-o>
                      <math-n>1.713</math-n>
                      <math-i>E</math-i>
                      <math-o>+</math-o>
                      <math-n>0.847</math-n>
                      <math-i>A</math-i>
                      <math-o>+</math-o>
                      <math-n>0.607</math-n>
                      <math-i>R</math-i>
                      <math-o>+</math-o>
                      <math-n>1.417</math-n>
                      <math-i>V</math-i>
                      <math-o>+</math-o>
                      <math-n>2.058</math-n>
                      <math-i>S</math-i>
                      <math-o>+</math-o>
                      <math-n>1.208</math-n>
                      <math-i>H</math-i>
                      <math-o>+</math-o>
                      <math-n>0.089</math-n>
                      <math-i>T</math-i>
                      <math-o>-</math-o>
                      <math-n>4.766</math-n>
                      <math-o>)</math-o>
                    </math-row>
                  </math-row>
                </math-sup>
              </math-row>
            </math-frac>
          </math-ml>
        </div>
        <p>Lorem ipsum dolor sit amet.</p>
      </div>
    </div>

    <button>Open tooltip</button>

    <script>
      const button = document.querySelector('button');
      const tooltip = document.querySelector('.tooltip');

      button.addEventListener('click', () => {
        tooltip.style.display = 'block';
      });

      setTimeout(() => {
        tooltip.style.display = 'block';
      }, 1000);
    </script>

    <div class="tooltip">
      <div class="tooltip__container">
        <h1>Always visible</h1>
        <div class="mathml-container">
          <math-ml display="block">
            <math-frac>
              <math-n>1</math-n>
              <math-row>
                <math-n>1</math-n>
                <math-o>+</math-o>
                <math-sup>
                  <math-i>e</math-i>
                  <math-row>
                    <math-o>-</math-o>
                    <math-row>
                      <math-o>(</math-o>
                      <math-n>1.713</math-n>
                      <math-i>E</math-i>
                      <math-o>+</math-o>
                      <math-n>0.847</math-n>
                      <math-i>A</math-i>
                      <math-o>+</math-o>
                      <math-n>0.607</math-n>
                      <math-i>R</math-i>
                      <math-o>+</math-o>
                      <math-n>1.417</math-n>
                      <math-i>V</math-i>
                      <math-o>+</math-o>
                      <math-n>2.058</math-n>
                      <math-i>S</math-i>
                      <math-o>+</math-o>
                      <math-n>1.208</math-n>
                      <math-i>H</math-i>
                      <math-o>+</math-o>
                      <math-n>0.089</math-n>
                      <math-i>T</math-i>
                      <math-o>-</math-o>
                      <math-n>4.766</math-n>
                      <math-o>)</math-o>
                    </math-row>
                  </math-row>
                </math-sup>
              </math-row>
            </math-frac>
          </math-ml>
        </div>
        <p>Lorem ipsum dolor sit amet.</p>
      </div>
    </div>

    <script>
      const mathDefinitions = new WeakMap();
      (() => {
        const mathElements = document.querySelectorAll('math-ml');
        for (const mathElement of mathElements) {
          mathDefinitions.set(mathElement, mathElement.innerHTML);
        }
      })();

      const observer = new MutationObserver((mutationsList) => {
        for (mutation of mutationsList) {
          const mathElements = mutation.target.querySelectorAll('math-ml');
          for (const mathElement of mathElements) {
            if (mathElement.offsetParent !== null) {
              const definition = mathDefinitions.get(mathElement);
              if (definition) {
                console.log('re-render math expression definition', definition);
                mathElement.innerHTML = definition;
              }
            }
          }
        }
      });

      observer.observe(document.body, {
        attributes: true,
        attributeFilter: ['style'],
        subtree: true
      });
    </script>

    <script src="https://unpkg.com/mathml-elements@latest/dist/bundled/mathml.min.js"></script>
  </body>
</html>

tirithen avatar Apr 27 '20 17:04 tirithen