Always deal with calc() in CSS pixels.

A bunch of the new math functions deal strictly with CSS pixels, so
let's try to remove the nscoord-resolving code-path from
StyleCalcNode::ResolveInternal.

This simplifies the code and adding new math functions, and in practice
it's the right thing to do, since if you subtract percentages, you
don't want to truncate the same way as if you were adding them.

Behavior wise this could cause subpixel differences, but in general it
should be for the better, per the above comment.

Co-authored-by: Tiaan Louw <tlouw@mozilla.com>

Differential Revision: https://phabricator.services.mozilla.com/D182713

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1841612
gecko-commit: 422af19ca706a86ef5b9a2ad0fa46e701b8a137d
gecko-reviewers: tlouw
diff --git a/css/css-values/round-mod-rem-computed.html b/css/css-values/round-mod-rem-computed.html
index 2210f6e..c5d05f1 100644
--- a/css/css-values/round-mod-rem-computed.html
+++ b/css/css-values/round-mod-rem-computed.html
@@ -125,7 +125,7 @@
 test_math_used('mod(100px,1rem)', '4px');
 test_math_used('mod(10s,6000ms)', '4s', {type:'time'});
 test_math_used('mod(10000ms,6s)', '4s', {type:'time'});
-test_math_used('mod(18px,100% / 15)', '3px');
+test_math_used('mod(18px,100% / 15)', '3px', {approx: 0.1});
 test_math_used('mod(-18px,100% / 10)', '4.5px');
 test_math_used('mod(18%,5%)', '3%');
 test_math_used('mod(-19%,5%)', '1%');
@@ -138,8 +138,8 @@
 test_math_used('rem(100px,1rem)', '4px');
 test_math_used('rem(10s,6000ms)', '4s', {type:'time'});
 test_math_used('rem(10000ms,6s)', '4s', {type:'time'});
-test_math_used('rem(18px,100% / 15)', '3px');
-test_math_used('rem(-18px,100% / 15)', '-3px');
+test_math_used('rem(18px,100% / 15)', '3px', {approx: 0.1});
+test_math_used('rem(-18px,100% / 15)', '-3px', {approx: 0.1});
 test_math_used('rem(18vw,5vw)', '3vw');
 test_math_used('rem(-18vw,5vw)', '-3vw');
 
diff --git a/css/support/numeric-testcommon.js b/css/support/numeric-testcommon.js
index 3a39e2a..ea1762e 100644
--- a/css/support/numeric-testcommon.js
+++ b/css/support/numeric-testcommon.js
@@ -185,9 +185,15 @@
         testEl.style[prop] = e;
         const expectedValue = getComputedStyle(testEl)[prop];
         assert_not_equals(expectedValue, defaultValue, `${expectedString} isn't valid in '${prop}'; got the default value instead.`)
-        if(approx && (type == "number" || type == "angle")){
-            let parsedUsed = usedValue.split('(')[1].split(')')[0].split(',').map(parseFloat);
-            let parsedExpected = expectedValue.split('(')[1].split(')')[0].split(',').map(parseFloat);
+        if (approx) {
+            let extractValues = function(value) {
+                if (type == "number" || type == "angle") {
+                    return value.split('(')[1].split(')')[0].split(',').map(parseFloat);
+                }
+                return [parseFloat(value)];
+            };
+            let parsedUsed = extractValues(usedValue);
+            let parsedExpected = extractValues(expectedValue);
             assert_array_approx_equals(parsedUsed, parsedExpected, approx, `${testString} and ${expectedString} ${approx} serialize to the same thing in ${stage} values.`);
         } else {
             assert_equals(usedValue, expectedValue, `${testString} and ${expectedString} serialize to the same thing in ${stage} values.`);