export function parseOffset()

in SampleWebApplication/MVC5App/Scripts/src/modifiers/offset.js [75:156]


export function parseOffset(
  offset,
  popperOffsets,
  referenceOffsets,
  basePlacement
) {
  const offsets = [0, 0];

  // Use height if placement is left or right and index is 0 otherwise use width
  // in this way the first offset will use an axis and the second one
  // will use the other one
  const useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;

  // Split the offset string to obtain a list of values and operands
  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
  const fragments = offset.split(/(\+|\-)/).map(frag => frag.trim());

  // Detect if the offset string contains a pair of values or a single one
  // they could be separated by comma or space
  const divider = fragments.indexOf(
    find(fragments, frag => frag.search(/,|\s/) !== -1)
  );

  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
    console.warn(
      'Offsets separated by white space(s) are deprecated, use a comma (,) instead.'
    );
  }

  // If divider is found, we divide the list of values and operands to divide
  // them by ofset X and Y.
  const splitRegex = /\s*,\s*|\s+/;
  let ops = divider !== -1
    ? [
        fragments
          .slice(0, divider)
          .concat([fragments[divider].split(splitRegex)[0]]),
        [fragments[divider].split(splitRegex)[1]].concat(
          fragments.slice(divider + 1)
        ),
      ]
    : [fragments];

  // Convert the values with units to absolute pixels to allow our computations
  ops = ops.map((op, index) => {
    // Most of the units rely on the orientation of the popper
    const measurement = (index === 1 ? !useHeight : useHeight)
      ? 'height'
      : 'width';
    let mergeWithPrevious = false;
    return (
      op
        // This aggregates any `+` or `-` sign that aren't considered operators
        // e.g.: 10 + +5 => [10, +, +5]
        .reduce((a, b) => {
          if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
            a[a.length - 1] = b;
            mergeWithPrevious = true;
            return a;
          } else if (mergeWithPrevious) {
            a[a.length - 1] += b;
            mergeWithPrevious = false;
            return a;
          } else {
            return a.concat(b);
          }
        }, [])
        // Here we convert the string values into number values (in px)
        .map(str => toValue(str, measurement, popperOffsets, referenceOffsets))
    );
  });

  // Loop trough the offsets arrays and execute the operations
  ops.forEach((op, index) => {
    op.forEach((frag, index2) => {
      if (isNumeric(frag)) {
        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
      }
    });
  });
  return offsets;
}