source: trip-planner-front/node_modules/svgo/plugins/removeOffCanvasPaths.js@ ceaed42

Last change on this file since ceaed42 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.9 KB
RevLine 
[6a3a178]1'use strict';
2
3/**
4 * @typedef {import('../lib/types').PathDataItem} PathDataItem
5 */
6
7const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
8const { parsePathData } = require('../lib/path.js');
9const { intersects } = require('./_path.js');
10
11exports.type = 'visitor';
12exports.name = 'removeOffCanvasPaths';
13exports.active = false;
14exports.description =
15 'removes elements that are drawn outside of the viewbox (disabled by default)';
16
17/**
18 * Remove elements that are drawn outside of the viewbox.
19 *
20 * @author JoshyPHP
21 *
22 * @type {import('../lib/types').Plugin<void>}
23 */
24exports.fn = () => {
25 /**
26 * @type {null | {
27 * top: number,
28 * right: number,
29 * bottom: number,
30 * left: number,
31 * width: number,
32 * height: number
33 * }}
34 */
35 let viewBoxData = null;
36
37 return {
38 element: {
39 enter: (node, parentNode) => {
40 if (node.name === 'svg' && parentNode.type === 'root') {
41 let viewBox = '';
42 // find viewbox
43 if (node.attributes.viewBox != null) {
44 // remove commas and plus signs, normalize and trim whitespace
45 viewBox = node.attributes.viewBox;
46 } else if (
47 node.attributes.height != null &&
48 node.attributes.width != null
49 ) {
50 viewBox = `0 0 ${node.attributes.width} ${node.attributes.height}`;
51 }
52
53 // parse viewbox
54 // remove commas and plus signs, normalize and trim whitespace
55 viewBox = viewBox
56 .replace(/[,+]|px/g, ' ')
57 .replace(/\s+/g, ' ')
58 .replace(/^\s*|\s*$/g, '');
59 // ensure that the dimensions are 4 values separated by space
60 const m =
61 /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(
62 viewBox
63 );
64 if (m == null) {
65 return;
66 }
67 const left = Number.parseFloat(m[1]);
68 const top = Number.parseFloat(m[2]);
69 const width = Number.parseFloat(m[3]);
70 const height = Number.parseFloat(m[4]);
71
72 // store the viewBox boundaries
73 viewBoxData = {
74 left,
75 top,
76 right: left + width,
77 bottom: top + height,
78 width,
79 height,
80 };
81 }
82
83 // consider that any item with a transform attribute is visible
84 if (node.attributes.transform != null) {
85 return visitSkip;
86 }
87
88 if (
89 node.name === 'path' &&
90 node.attributes.d != null &&
91 viewBoxData != null
92 ) {
93 const pathData = parsePathData(node.attributes.d);
94
95 // consider that a M command within the viewBox is visible
96 let visible = false;
97 for (const pathDataItem of pathData) {
98 if (pathDataItem.command === 'M') {
99 const [x, y] = pathDataItem.args;
100 if (
101 x >= viewBoxData.left &&
102 x <= viewBoxData.right &&
103 y >= viewBoxData.top &&
104 y <= viewBoxData.bottom
105 ) {
106 visible = true;
107 }
108 }
109 }
110 if (visible) {
111 return;
112 }
113
114 if (pathData.length === 2) {
115 // close the path too short for intersects()
116 pathData.push({ command: 'z', args: [] });
117 }
118
119 const { left, top, width, height } = viewBoxData;
120 /**
121 * @type {Array<PathDataItem>}
122 */
123 const viewBoxPathData = [
124 { command: 'M', args: [left, top] },
125 { command: 'h', args: [width] },
126 { command: 'v', args: [height] },
127 { command: 'H', args: [left] },
128 { command: 'z', args: [] },
129 ];
130
131 if (intersects(viewBoxPathData, pathData) === false) {
132 detachNodeFromParent(node, parentNode);
133 }
134 }
135 },
136 },
137 };
138};
Note: See TracBrowser for help on using the repository browser.