| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 | 'use strict';exports.type = 'perItemReverse';exports.active = true;exports.description = 'moves elements attributes to the existing group wrapper';var inheritableAttrs = require('./_collections').inheritableAttrs,    pathElems = require('./_collections.js').pathElems;/** * Collapse content's intersected and inheritable * attributes to the existing group wrapper. * * @example * <g attr1="val1"> *     <g attr2="val2"> *         text *     </g> *     <circle attr2="val2" attr3="val3"/> * </g> *              ⬇ * <g attr1="val1" attr2="val2"> *     <g> *         text *     </g> *    <circle attr3="val3"/> * </g> * * @param {Object} item current iteration item * @return {Boolean} if false, item will be filtered out * * @author Kir Belevich */exports.fn = function(item) {    if (item.isElem('g') && !item.isEmpty() && item.content.length > 1) {        var intersection = {},            hasTransform = false,            hasClip = item.hasAttr('clip-path') || item.hasAttr('mask'),            intersected = item.content.every(function(inner) {                if (inner.isElem() && inner.hasAttr()) {                    // don't mess with possible styles (hack until CSS parsing is implemented)                    if (inner.hasAttr('class')) return false;                    if (!Object.keys(intersection).length) {                        intersection = inner.attrs;                    } else {                        intersection = intersectInheritableAttrs(intersection, inner.attrs);                        if (!intersection) return false;                    }                    return true;                }            }),            allPath = item.content.every(function(inner) {                return inner.isElem(pathElems);            });        if (intersected) {            item.content.forEach(function(g) {                for (var name in intersection) {                    if (!allPath && !hasClip || name !== 'transform') {                        g.removeAttr(name);                        if (name === 'transform') {                            if (!hasTransform) {                                if (item.hasAttr('transform')) {                                    item.attr('transform').value += ' ' + intersection[name].value;                                } else {                                    item.addAttr(intersection[name]);                                }                                hasTransform = true;                            }                        } else {                            item.addAttr(intersection[name]);                        }                    }                }            });        }    }};/** * Intersect inheritable attributes. * * @param {Object} a first attrs object * @param {Object} b second attrs object * * @return {Object} intersected attrs object */function intersectInheritableAttrs(a, b) {    var c = {};    for (var n in a) {        if (            b.hasOwnProperty(n) &&            inheritableAttrs.indexOf(n) > -1 &&            a[n].name === b[n].name &&            a[n].value === b[n].value &&            a[n].prefix === b[n].prefix &&            a[n].local === b[n].local        ) {            c[n] = a[n];        }    }    if (!Object.keys(c).length) return false;    return c;}
 |