tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

animated-path-helpers.js (3066B)


      1 function roundNumbers(value, digits) {
      2  // Round numbers to |digits| decimal places.
      3  return value.
      4    replace(/-?\d*\.\d+(e-?\d+)?/g, function(n) {
      5      return (parseFloat(n).toFixed(digits)).
      6        replace(/\.\d+/, function(m) {
      7          return m.replace(/0+$/, '');
      8        }).
      9        replace(/\.$/, '').
     10        replace(/^-0$/, '0');
     11    });
     12 }
     13 
     14 function normalizeValue(value, digits) {
     15  // Round numbers and place whitespace between tokens.
     16  return roundNumbers(value, digits).
     17    replace(/([\w\d.]+|[^\s])/g, '$1 ').
     18    replace(/\s+/g, ' ');
     19 }
     20 
     21 // Transform a path seg list into a path string, rounding numbers to |digits|
     22 // decimal places.
     23 function serializePathSegList(list, digits) {
     24  function segmentArguments(segment) {
     25    const kCommandDescriptor = {
     26      'M': ['x', 'y'],
     27      'L': ['x', 'y'],
     28      'C': ['x1', 'y1', 'x2', 'y2', 'x', 'y'],
     29      'Q': ['x1', 'y1', 'x', 'y'],
     30      'S': ['x2', 'y2', 'x', 'y'],
     31      'T': ['x', 'y'],
     32      'A': ['r1', 'r2', 'angle', 'largeArcFlag', 'sweepFlag', 'x', 'y'],
     33      'H': ['x'],
     34      'V': ['y'],
     35      'Z': []
     36    };
     37    let command = segment.pathSegTypeAsLetter.toUpperCase();
     38    return kCommandDescriptor[command].map(field => {
     39      return Number(segment[field]).toFixed(digits);
     40    });
     41  }
     42  return Array.from(list).map(segment => {
     43    let command = segment.pathSegTypeAsLetter;
     44    if (command === 'z')
     45      command = 'Z';
     46    return [command, ...segmentArguments(segment)].join(' ');
     47  }).join(' ');
     48 }
     49 
     50 function normalizeProperty(path_string) {
     51  let probePathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
     52  probePathElement.setAttribute('d', path_string);
     53  document.documentElement.appendChild(probePathElement);
     54  let string = getComputedStyle(probePathElement).getPropertyValue('d');
     55  probePathElement.remove();
     56  return string;
     57 }
     58 
     59 // Assert that the animated path data of |target| matches one of
     60 // |expected_paths|. Numbers will be rounded to 2 decimal places.
     61 function assert_animated_path_in_array(target, expected_paths) {
     62  const kDecimals = 2;
     63  let expected, actual;
     64  if ('animatedPathSegList' in target) {
     65    let probePathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
     66    expected = expected_paths.map(p => {
     67      probePathElement.setAttribute('d', p);
     68      return serializePathSegList(probePathElement.pathSegList, kDecimals)
     69    });
     70    actual = serializePathSegList(target.animatedPathSegList, kDecimals);
     71  } else if ('d' in target.style) {
     72    expected = expected_paths.map(p => normalizeValue(normalizeProperty(p), kDecimals));
     73    actual = normalizeValue(getComputedStyle(target).getPropertyValue('d'), kDecimals);
     74  } else {
     75    assert_unreached('no animated path data');
     76  }
     77  assert_in_array(actual, expected);
     78 }
     79 
     80 // Assert that the animated path data of |target| matches that of
     81 // |expected_path_string|. Numbers will be rounded to 2 decimal places.
     82 function assert_animated_path_equals(target, expected_path_string) {
     83  return assert_animated_path_in_array(target, [expected_path_string]);
     84 }