All files / src/plugins mergePaths.ts

10% Statements 2/20
0% Branches 0/24
0% Functions 0/3
10% Lines 2/20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 721x                                                                                                                       1x                      
import { intersects, js2path, path2js } from './_path';
 
import { JsApi } from '../jsapi';
import { Plugin } from './_types';
 
export interface Params {
  collapseRepeated: boolean;
  leadingZero: boolean;
  negativeExtraSpace: boolean;
}
 
/**
 * Merge multiple paths into one.
 */
function fn(item: JsApi, params: Params) {
  if (!item.isElem() || item.isEmpty()) {
    return item;
  }
 
  let prevContentItem: JsApi;
  let prevContentItemKeys: string[];
 
  item.content = item.content.filter(contentItem => {
    if (
      prevContentItem &&
      prevContentItem.isElem('path') &&
      prevContentItem.isEmpty() &&
      prevContentItem.hasAttr('android:pathData') &&
      contentItem.isElem('path') &&
      contentItem.isEmpty() &&
      contentItem.hasAttr('android:pathData')
    ) {
      if (!prevContentItemKeys) {
        prevContentItemKeys = Object.keys(prevContentItem.attrs);
      }
      const contentItemAttrs = Object.keys(contentItem.attrs);
      const equalData =
        prevContentItemKeys.length === contentItemAttrs.length &&
        contentItemAttrs.every(key => {
          return (
            key === 'android:pathData' ||
            (prevContentItem.hasAttr(key) &&
              prevContentItem.attr(key).value === contentItem.attr(key).value)
          );
        });
      const prevPathJS = path2js(prevContentItem);
      const curPathJS = path2js(contentItem);
      if (equalData && !intersects(prevPathJS, curPathJS)) {
        js2path(prevContentItem, prevPathJS.concat(curPathJS), params);
        return false;
      }
    }
    prevContentItem = contentItem;
    prevContentItemKeys = undefined;
    return true;
  });
 
  return item;
}
 
export const mergePaths: Plugin<Params> = {
  type: 'perItem',
  active: true,
  description: 'merges multiple paths into one, if possible',
  params: {
    collapseRepeated: true,
    leadingZero: true,
    negativeExtraSpace: true,
  },
  fn,
};