123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- 'use strict';
- const { visit } = require('../lib/xast.js');
- const { inheritableAttrs, pathElems } = require('./_collections.js');
- exports.type = 'visitor';
- exports.name = 'moveElemsAttrsToGroup';
- exports.active = true;
- exports.description = 'Move common attributes of group children to the group';
- exports.fn = (root) => {
-
- let deoptimizedWithStyles = false;
- visit(root, {
- element: {
- enter: (node) => {
- if (node.name === 'style') {
- deoptimizedWithStyles = true;
- }
- },
- },
- });
- return {
- element: {
- exit: (node) => {
-
- if (node.name !== 'g' || node.children.length <= 1) {
- return;
- }
-
-
- if (deoptimizedWithStyles) {
- return;
- }
-
- const commonAttributes = new Map();
- let initial = true;
- let everyChildIsPath = true;
- for (const child of node.children) {
- if (child.type === 'element') {
- if (pathElems.includes(child.name) === false) {
- everyChildIsPath = false;
- }
- if (initial) {
- initial = false;
-
- for (const [name, value] of Object.entries(child.attributes)) {
-
- if (inheritableAttrs.includes(name)) {
- commonAttributes.set(name, value);
- }
- }
- } else {
-
- for (const [name, value] of commonAttributes) {
- if (child.attributes[name] !== value) {
- commonAttributes.delete(name);
- }
- }
- }
- }
- }
-
- if (
- node.attributes['clip-path'] != null ||
- node.attributes.mask != null
- ) {
- commonAttributes.delete('transform');
- }
-
-
- if (everyChildIsPath) {
- commonAttributes.delete('transform');
- }
-
- for (const [name, value] of commonAttributes) {
- if (name === 'transform') {
- if (node.attributes.transform != null) {
- node.attributes.transform = `${node.attributes.transform} ${value}`;
- } else {
- node.attributes.transform = value;
- }
- } else {
- node.attributes[name] = value;
- }
- }
-
- for (const child of node.children) {
- if (child.type === 'element') {
- for (const [name] of commonAttributes) {
- delete child.attributes[name];
- }
- }
- }
- },
- },
- };
- };
|