* Parse an `offset` string to extrapolate `x` and `y` numeric offsets. * @function * @memberof {modifiers~offset} * @private * @argument {String} offset * @argument {Object} popperOffsets * @argument {Object} referenceOffsets * @argument {String} basePlacement * @returns {Array} a two cells
(offset, popperOffsets, referenceOffsets, basePlacement)
| 4704 | |
| 4705 | |
| 4706 | function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { |
| 4707 | var offsets = [0, 0]; // Use height if placement is left or right and index is 0 otherwise use width |
| 4708 | // in this way the first offset will use an axis and the second one |
| 4709 | // will use the other one |
| 4710 | |
| 4711 | var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; // Split the offset string to obtain a list of values and operands |
| 4712 | // The regex addresses values with the plus or minus sign in front (+10, -20, etc) |
| 4713 | |
| 4714 | var fragments = offset.split(/(\+|\-)/).map(function (frag) { |
| 4715 | return frag.trim(); |
| 4716 | }); // Detect if the offset string contains a pair of values or a single one |
| 4717 | // they could be separated by comma or space |
| 4718 | |
| 4719 | var divider = fragments.indexOf(find(fragments, function (frag) { |
| 4720 | return frag.search(/,|\s/) !== -1; |
| 4721 | })); |
| 4722 | |
| 4723 | if (fragments[divider] && fragments[divider].indexOf(',') === -1) { |
| 4724 | console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); |
| 4725 | } // If divider is found, we divide the list of values and operands to divide |
| 4726 | // them by ofset X and Y. |
| 4727 | |
| 4728 | |
| 4729 | var splitRegex = /\s*,\s*|\s+/; |
| 4730 | var 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 |
| 4731 | |
| 4732 | ops = ops.map(function (op, index) { |
| 4733 | // Most of the units rely on the orientation of the popper |
| 4734 | var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; |
| 4735 | var mergeWithPrevious = false; |
| 4736 | return op // This aggregates any `+` or `-` sign that aren't considered operators |
| 4737 | // e.g.: 10 + +5 => [10, +, +5] |
| 4738 | .reduce(function (a, b) { |
| 4739 | if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { |
| 4740 | a[a.length - 1] = b; |
| 4741 | mergeWithPrevious = true; |
| 4742 | return a; |
| 4743 | } else if (mergeWithPrevious) { |
| 4744 | a[a.length - 1] += b; |
| 4745 | mergeWithPrevious = false; |
| 4746 | return a; |
| 4747 | } else { |
| 4748 | return a.concat(b); |
| 4749 | } |
| 4750 | }, []) // Here we convert the string values into number values (in px) |
| 4751 | .map(function (str) { |
| 4752 | return toValue(str, measurement, popperOffsets, referenceOffsets); |
| 4753 | }); |
| 4754 | }); // Loop trough the offsets arrays and execute the operations |
| 4755 | |
| 4756 | ops.forEach(function (op, index) { |
| 4757 | op.forEach(function (frag, index2) { |
| 4758 | if (isNumeric(frag)) { |
| 4759 | offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); |
| 4760 | } |
| 4761 | }); |
| 4762 | }); |
| 4763 | return offsets; |