[mathml] Refactor parsing of mspace and mpadded attributes

Currently, the mspace and mpadded elements use different approaches
to parse the width/height/depth/lspace/voffset attributes:

- AddPropertyToPresentationAttributeStyle for the value (sometimes
  excluding values that ends with a '%' character).

- AddPropertyToPresentationAttributeStyle for a calc expression
  built from the values of the height and depth attributes.

- Using AddMathLengthToComputedStyle (sometimes accepting percentage)
  which relies on CSSParser::ParseLengthPercentage, but these parsing
  methods seem incorrect.

The initial goal was to use the default value when a percentage is
specified and this is what is currently specified in MathML Core
[1] [2]. However, the current implementation has bugs that make
percentage accepted in some cases [3] or unnecessarily mapping
invalid values to presentational hints.

This CL tries to bring more consistency on the parsing side by always
delegating the parsing of the attribute value to
CSSParser::ParseLengthPercentage before mapping it to presentational
hint or internal properties. The parsing parameter
AllowPercentages::kNo is used to ensure percentages are always
treated as invalid. CSSParser::ParseLengthPercentage is also refine to
always trim whitespaces, and check there is no remaining token after
the parsed <length-percentage>.

This refactoring will facilitate specifying Chrome's behavior in
MathML Core regarding interaction with CSS width/height properties,
handling of percentages and use of presentational hints [4].

[1] https://w3c.github.io/mathml-core/#space-mspace
[2] https://w3c.github.io/mathml-core/#inner-box-and-requested-parameters
[3] crbug.com/1402998
[4] https://github.com/w3c/mathml-core/issues/75#issuecomment-1359541618

Bug: 6606, 1402998
Change-Id: Ibe4e49af4c3f4aeb5c153e10b4ba93d26db20849
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4120274
Commit-Queue: Frédéric Wang <fwang@igalia.com>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1090758}
diff --git a/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html b/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html
new file mode 100644
index 0000000..79d7df3
--- /dev/null
+++ b/mathml/presentation-markup/mpadded/mpadded-percentage-001-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>mpadded percentages (reference)</title>
+    <style>
+      .red {
+          background: red;
+      }
+    </style>
+  </head>
+  <body>
+    <p>This test passes if there is a green square with no red.</p>
+    <math display="block"
+          style="width: 200px; height: 200px; background: green">
+    </math>
+  </body>
+</html>
diff --git a/mathml/presentation-markup/mpadded/mpadded-percentage-001.html b/mathml/presentation-markup/mpadded/mpadded-percentage-001.html
new file mode 100644
index 0000000..ef2391c
--- /dev/null
+++ b/mathml/presentation-markup/mpadded/mpadded-percentage-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>mpadded percentages</title>
+    <link rel="help" href="https://w3c.github.io/mathml-core/#inner-box-and-requested-parameters">
+    <meta name="assert" content="Verify that percentage values for mpadded do not use refer to the containing block">
+    <link rel="match" href="mpadded-percentage-001-ref.html">
+    <style>
+      .red {
+          background: red;
+      }
+    </style>
+  </head>
+  <body>
+    <p>This test passes if there is a green square with no red.</p>
+    <math display="block"
+          style="width: 200px; height: 200px; background: green">
+      <mpadded width="5%" height="10px" class="red"></mpadded>
+      <mpadded width=" 5%" height="10px" class="red"></mpadded>
+      <mpadded width="5% " height="10px" class="red"></mpadded>
+      <mpadded width="10px" height="5%" class="red"></mpadded>
+      <mpadded width="10px" height=" 5%" class="red"></mpadded>
+      <mpadded width="10px" height="5% " class="red"></mpadded>
+      <mpadded width="10px" depth="5%" class="red"></mpadded>
+      <mpadded width="10px" depth=" 5%" class="red"></mpadded>
+      <mpadded width="10px" depth="5% " class="red"></mpadded>
+      <mpadded width="10px" height="5%" depth="5%" class="red"></mpadded>
+      <mpadded width="10px" height=" 5%" depth=" 5%" class="red"></mpadded>
+      <mpadded width="10px" height="5% " depth="5% " class="red"></mpadded>
+    </math>
+  </body>
+</html>
diff --git a/mathml/presentation-markup/mpadded/mpadded-percentage-002.html b/mathml/presentation-markup/mpadded/mpadded-percentage-002.html
new file mode 100644
index 0000000..36d1b4f
--- /dev/null
+++ b/mathml/presentation-markup/mpadded/mpadded-percentage-002.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title></title>
+    <link rel="help" href="https://w3c.github.io/mathml-core/#adjust-space-around-content-mpadded">
+    <meta name="assert" content="Percentage values are interpreted as the default value">
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+    <script src="/mathml/support/feature-detection.js"></script>
+    <script src="/mathml/support/layout-comparison.js"></script>
+    <style>
+      .testedElement {
+          background: red;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="log"></div>
+
+    <p>
+      <math>
+        <mpadded id="reference">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <p>
+      <math>
+        <mpadded class="testedElement" width="200%">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <p>
+      <math>
+        <mpadded class="testedElement" height="200%">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <p>
+      <math>
+        <mpadded class="testedElement" depth="200%">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <p>
+      <math>
+        <mpadded class="testedElement" lspace="200%">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <p>
+      <math>
+        <mpadded class="testedElement" voffset="200%">
+          <mspace width="10px" height="20px" depth="30px"
+                  style="background: blue"/>
+        </mpadded>
+      </math>
+    </p>
+    <script type="text/javascript">
+      Array.from(document.getElementsByClassName("testedElement")).forEach(mpadded => {
+          var reference = document.getElementById("reference");
+          const name = ["width", "depth", "height", "lspace", "voffset"].find(attr => mpadded.hasAttribute(attr));
+          const epsilon = 1;
+          test(function() {
+              assert_true(MathMLFeatureDetection.has_mspace());
+              compareLayout(mpadded, reference, epsilon);
+          }, `${name}='${mpadded.getAttribute(name)}' is interpreted as the default value`);
+      });
+    </script>
+  </body>
+</html>
diff --git a/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html b/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html
new file mode 100644
index 0000000..da4f1dd
--- /dev/null
+++ b/mathml/presentation-markup/spaces/mspace-percentage-001-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>mspace percentages (reference)</title>
+    <style>
+      .red {
+          background: red;
+      }
+    </style>
+  </head>
+  <body>
+    <p>This test passes if there is a green square with no red.</p>
+    <math display="block"
+          style="width: 200px; height: 200px; background: green">
+    </math>
+  </body>
+</html>
diff --git a/mathml/presentation-markup/spaces/mspace-percentage-001.html b/mathml/presentation-markup/spaces/mspace-percentage-001.html
new file mode 100644
index 0000000..758429e
--- /dev/null
+++ b/mathml/presentation-markup/spaces/mspace-percentage-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>mspace percentages</title>
+    <link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+    <meta name="assert" content="Verify that percentage values for mspace do not use refer to the containing block">
+    <link rel="match" href="mspace-percentage-001-ref.html">
+    <style>
+      .red {
+          background: red;
+      }
+    </style>
+  </head>
+  <body>
+    <p>This test passes if there is a green square with no red.</p>
+    <math display="block"
+          style="width: 200px; height: 200px; background: green">
+      <mspace width="5%" height="10px" class="red"></mspace>
+      <mspace width=" 5%" height="10px" class="red"></mspace>
+      <mspace width="5% " height="10px" class="red"></mspace>
+      <mspace width="10px" height="5%" class="red"></mspace>
+      <mspace width="10px" height=" 5%" class="red"></mspace>
+      <mspace width="10px" height="5% " class="red"></mspace>
+      <mspace width="10px" depth="5%" class="red"></mspace>
+      <mspace width="10px" depth=" 5%" class="red"></mspace>
+      <mspace width="10px" depth="5% " class="red"></mspace>
+      <mspace width="10px" height="5%" depth="5%" class="red"></mspace>
+      <mspace width="10px" height=" 5%" depth=" 5%" class="red"></mspace>
+      <mspace width="10px" height="5% " depth="5% " class="red"></mspace>
+    </math>
+  </body>
+</html>