| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 | 'use strict';exports.name = 'removeAttrs';exports.type = 'visitor';exports.active = false;exports.description = 'removes specified attributes';const DEFAULT_SEPARATOR = ':';const ENOATTRS = `Warning: The plugin "removeAttrs" requires the "attrs" parameter.It should have a pattern to remove, otherwise the plugin is a noop.Config example:plugins: [  {    name: "removeAttrs",    params: {      attrs: "(fill|stroke)"    }  }]`;/** * Remove attributes * * @example elemSeparator *   format: string * * @example preserveCurrentColor *   format: boolean * * @example attrs: * *   format: [ element* : attribute* : value* ] * *   element   : regexp (wrapped into ^...$), single * or omitted > all elements (must be present when value is used) *   attribute : regexp (wrapped into ^...$) *   value     : regexp (wrapped into ^...$), single * or omitted > all values * *   examples: * *     > basic: remove fill attribute *     --- *     removeAttrs: *       attrs: 'fill' * *     > remove fill attribute on path element *     --- *       attrs: 'path:fill' * *     > remove fill attribute on path element where value is none *     --- *       attrs: 'path:fill:none' * * *     > remove all fill and stroke attribute *     --- *       attrs: *         - 'fill' *         - 'stroke' * *     [is same as] * *       attrs: '(fill|stroke)' * *     [is same as] * *       attrs: '*:(fill|stroke)' * *     [is same as] * *       attrs: '.*:(fill|stroke)' * *     [is same as] * *       attrs: '.*:(fill|stroke):.*' * * *     > remove all stroke related attributes *     ---- *     attrs: 'stroke.*' * * * @author Benny Schudel * * @type {import('../lib/types').Plugin<{ *   elemSeparator?: string, *   preserveCurrentColor?: boolean, *   attrs: string | Array<string> * }>} */exports.fn = (root, params) => {  if (typeof params.attrs == 'undefined') {    console.warn(ENOATTRS);    return null;  }  const elemSeparator =    typeof params.elemSeparator == 'string'      ? params.elemSeparator      : DEFAULT_SEPARATOR;  const preserveCurrentColor =    typeof params.preserveCurrentColor == 'boolean'      ? params.preserveCurrentColor      : false;  const attrs = Array.isArray(params.attrs) ? params.attrs : [params.attrs];  return {    element: {      enter: (node) => {        for (let pattern of attrs) {          // if no element separators (:), assume it's attribute name, and apply to all elements *regardless of value*          if (pattern.includes(elemSeparator) === false) {            pattern = ['.*', elemSeparator, pattern, elemSeparator, '.*'].join(              ''            );            // if only 1 separator, assume it's element and attribute name, and apply regardless of attribute value          } else if (pattern.split(elemSeparator).length < 3) {            pattern = [pattern, elemSeparator, '.*'].join('');          }          // create regexps for element, attribute name, and attribute value          const list = pattern.split(elemSeparator).map((value) => {            // adjust single * to match anything            if (value === '*') {              value = '.*';            }            return new RegExp(['^', value, '$'].join(''), 'i');          });          // matches element          if (list[0].test(node.name)) {            // loop attributes            for (const [name, value] of Object.entries(node.attributes)) {              const isFillCurrentColor =                preserveCurrentColor &&                name == 'fill' &&                value == 'currentColor';              const isStrokeCurrentColor =                preserveCurrentColor &&                name == 'stroke' &&                value == 'currentColor';              if (                !isFillCurrentColor &&                !isStrokeCurrentColor &&                // matches attribute name                list[1].test(name) &&                // matches attribute value                list[2].test(value)              ) {                delete node.attributes[name];              }            }          }        }      },    },  };};
 |