1 | 'use strict';
|
2 |
|
3 | exports.type = 'perItem';
|
4 |
|
5 | exports.active = false;
|
6 |
|
7 | exports.description = 'removes elements that are drawn outside of the viewbox (disabled by default)';
|
8 |
|
9 | var SVGO = require('../lib/svgo.js'),
|
10 | _path = require('./_path.js'),
|
11 | intersects = _path.intersects,
|
12 | path2js = _path.path2js,
|
13 | viewBox,
|
14 | viewBoxJS;
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | exports.fn = function(item) {
|
25 |
|
26 | if (item.isElem('path') && item.hasAttr('d') && typeof viewBox !== 'undefined')
|
27 | {
|
28 |
|
29 |
|
30 | if (hasTransform(item) || pathMovesWithinViewBox(item.attr('d').value))
|
31 | {
|
32 | return true;
|
33 | }
|
34 |
|
35 | var pathJS = path2js(item);
|
36 | if (pathJS.length === 2)
|
37 | {
|
38 |
|
39 | pathJS = JSON.parse(JSON.stringify(pathJS));
|
40 | pathJS.push({ instruction: 'z' });
|
41 | }
|
42 |
|
43 | return intersects(viewBoxJS, pathJS);
|
44 | }
|
45 | if (item.isElem('svg'))
|
46 | {
|
47 | parseViewBox(item);
|
48 | }
|
49 |
|
50 | return true;
|
51 | };
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | function hasTransform(item)
|
60 | {
|
61 | return item.hasAttr('transform') || (item.parentNode && hasTransform(item.parentNode));
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | function parseViewBox(svg)
|
70 | {
|
71 | var viewBoxData = '';
|
72 | if (svg.hasAttr('viewBox'))
|
73 | {
|
74 |
|
75 | viewBoxData = svg.attr('viewBox').value;
|
76 | }
|
77 | else if (svg.hasAttr('height') && svg.hasAttr('width'))
|
78 | {
|
79 | viewBoxData = '0 0 ' + svg.attr('width').value + ' ' + svg.attr('height').value;
|
80 | }
|
81 |
|
82 |
|
83 | viewBoxData = viewBoxData.replace(/[,+]|px/g, ' ').replace(/\s+/g, ' ').replace(/^\s*|\s*$/g, '');
|
84 |
|
85 |
|
86 | var m = /^(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+)$/.exec(viewBoxData);
|
87 | if (!m)
|
88 | {
|
89 | return;
|
90 | }
|
91 |
|
92 |
|
93 | viewBox = {
|
94 | left: parseFloat(m[1]),
|
95 | top: parseFloat(m[2]),
|
96 | right: parseFloat(m[1]) + parseFloat(m[3]),
|
97 | bottom: parseFloat(m[2]) + parseFloat(m[4])
|
98 | };
|
99 |
|
100 | var path = new SVGO().createContentItem({
|
101 | elem: 'path',
|
102 | prefix: '',
|
103 | local: 'path'
|
104 | });
|
105 | path.addAttr({
|
106 | name: 'd',
|
107 | prefix: '',
|
108 | local: 'd',
|
109 | value: 'M' + m[1] + ' ' + m[2] + 'h' + m[3] + 'v' + m[4] + 'H' + m[1] + 'z'
|
110 | });
|
111 |
|
112 | viewBoxJS = path2js(path);
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 | function pathMovesWithinViewBox(path)
|
122 | {
|
123 | var regexp = /M\s*(-?\d*\.?\d+)(?!\d)\s*(-?\d*\.?\d+)/g, m;
|
124 | while (null !== (m = regexp.exec(path)))
|
125 | {
|
126 | if (m[1] >= viewBox.left && m[1] <= viewBox.right && m[2] >= viewBox.top && m[2] <= viewBox.bottom)
|
127 | {
|
128 | return true;
|
129 | }
|
130 | }
|
131 |
|
132 | return false;
|
133 | }
|