| '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; |
| |
| } |