gulp-stacksvg 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +52 -133
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -5,148 +5,77 @@ import fancyLog from "fancy-log"
5
5
  import PluginError from "plugin-error"
6
6
  import Vinyl from "vinyl"
7
7
 
8
- const presentationAttributes = new Set([
9
- `alignment-baseline`,
10
- `baseline-shift`,
11
- `clip-path`,
12
- `clip-rule`,
13
- `clip`,
14
- `color-interpolation-filters`,
15
- `color-interpolation`,
16
- `color-profile`,
17
- `color-rendering`,
18
- `color`,
19
- `cursor`,
20
- `d`,
21
- `direction`,
22
- `display`,
23
- `dominant-baseline`,
8
+ const excessAttrs = [
24
9
  `enable-background`,
25
- `fill-opacity`,
26
- `fill-rule`,
27
- `fill`,
28
- `filter`,
29
- `flood-color`,
30
- `flood-opacity`,
31
- `font-family`,
32
- `font-size-adjust`,
33
- `font-size`,
34
- `font-stretch`,
35
- `font-style`,
36
- `font-variant`,
37
- `font-weight`,
38
- `glyph-orientation-horizontal`,
39
- `glyph-orientation-vertical`,
40
- `image-rendering`,
41
- `kerning`,
42
- `letter-spacing`,
43
- `lighting-color`,
44
- `marker-end`,
45
- `marker-mid`,
46
- `marker-start`,
47
- `mask`,
48
- `opacity`,
49
- `overflow`,
50
- `pointer-events`,
51
- `shape-rendering`,
52
- `solid-color`,
53
- `solid-opacity`,
54
- `stop-color`,
55
- `stop-opacity`,
56
- `stroke-dasharray`,
57
- `stroke-dashoffset`,
58
- `stroke-linecap`,
59
- `stroke-linejoin`,
60
- `stroke-miterlimit`,
61
- `stroke-opacity`,
62
- `stroke-width`,
63
- `stroke`,
64
- `style`,
65
- `text-anchor`,
66
- `text-decoration`,
67
- `text-rendering`,
68
- `transform`,
69
- `unicode-bidi`,
70
- `vector-effect`,
71
- `visibility`,
72
- `word-spacing`,
73
- `writing-mode`
74
- ])
75
-
76
- export function stacksvg (options) {
77
-
78
- options = options || {}
10
+ `height`,
11
+ `version`,
12
+ `width`,
13
+ `x`,
14
+ `xml:space`,
15
+ `y`
16
+ ]
79
17
 
80
- const ids = {}
81
- const namespaces = {}
82
- const separator = options.separator ?? `_`
83
- const spacer = options.spacer ?? `-`
18
+ export function stacksvg ({ output = `stack.svg`, separator = `_`, spacer = `-` } = {}) {
84
19
 
85
- let resultSvg = `<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>:root{visibility:hidden}:target{visibility:visible}</style><defs/></svg>`
86
20
  let isEmpty = true
87
- let fileName = options.output || `stack.svg`
88
-
89
- fileName = fileName.endsWith(`.svg`) ? fileName : `${fileName}.svg`
90
-
91
- const $ = load(resultSvg, { xmlMode: true })
92
- const $combinedSvg = $(`svg`)
93
- const $combinedDefs = $(`defs`)
21
+ const ids = {}
22
+ const namespaces = {}
23
+ const $stack = load(`<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg"><style>:root{visibility:hidden}:target{visibility:visible}</style></svg>`, { xmlMode: true })
24
+ const $rootSvg = $stack(`svg`)
94
25
  const stream = new Transform({ objectMode: true })
95
26
 
96
- stream._transform = function transform (file, _, cb) {
27
+ function transform (file, _, cb) {
97
28
 
98
29
  if (file.isStream()) {
99
30
  return cb(new PluginError(`gulp-stacksvg`, `Streams are not supported!`))
100
31
  }
101
32
 
102
- if (file.isNull()) {return cb()}
33
+ if (file.isNull()) {
34
+ return cb()
35
+ }
103
36
 
37
+ const $icon = load(file.contents.toString(), { xmlMode: true })(`svg`)
104
38
 
105
- const $svg = load(file.contents.toString(), { xmlMode: true })(`svg`)
39
+ if ($icon.length === 0) {
40
+ return cb()
41
+ }
106
42
 
107
- if ($svg.length === 0) {return cb()}
43
+ if (file && isEmpty) {
44
+ isEmpty = false
45
+ }
108
46
 
109
47
  const idAttr = basename(
110
48
  file.relative.split(sep).join(separator).replace(/\s/g, spacer),
111
49
  extname(file.relative)
112
50
  )
113
- const viewBoxAttr = $svg.attr(`viewBox`)
114
- const widthAttr = $svg.attr(`width`)
115
- const heightAttr = $svg.attr(`height`)
116
- const preserveAspectRatioAttr = $svg.attr(`preserveAspectRatio`)
117
- const $icon = $(`<svg/>`)
118
51
 
119
52
  if (idAttr in ids) {
120
53
  return cb(new PluginError(`gulp-stacksvg`, `File name should be unique: ${idAttr}`))
121
54
  }
122
55
 
123
56
  ids[idAttr] = true
57
+ $icon.attr(`id`, idAttr)
124
58
 
125
- if (file && isEmpty) {
126
- isEmpty = false
127
- }
59
+ const viewBoxAttr = $icon.attr(`viewBox`)
60
+ const widthAttr = $icon.attr(`width`)?.replace(/[^0-9]/g, ``)
61
+ const heightAttr = $icon.attr(`height`)?.replace(/[^0-9]/g, ``)
128
62
 
129
- $icon.attr(`id`, idAttr)
130
- if (viewBoxAttr) {
131
- $icon.attr(`viewBox`, viewBoxAttr)
132
- } else if (widthAttr && heightAttr) {
133
- $icon.attr(`viewBox`, `0 0 ${widthAttr.replace(/[^0-9]/g,``)} ${heightAttr.replace(/[^0-9]/g,``)}`)
134
- }
135
- if (preserveAspectRatioAttr) {
136
- $icon.attr(`preserveAspectRatio`, preserveAspectRatioAttr)
63
+ if (!viewBoxAttr && widthAttr && heightAttr) {
64
+ $icon.attr(`viewBox`, `0 0 ${widthAttr} ${heightAttr}`)
137
65
  }
138
66
 
139
- const attrs = $svg[0].attribs
67
+ excessAttrs.forEach((attr) => $icon.removeAttr(attr))
68
+
69
+ const attrs = $icon[0].attribs
70
+
140
71
  for (let attrName in attrs) {
141
- if (attrName.match(/xmlns:.+/)) {
72
+ if (attrName.startsWith(`xmlns`)) {
142
73
  const storedNs = namespaces[attrName]
143
74
  const attrNs = attrs[attrName]
144
75
 
145
76
  if (storedNs !== undefined) {
146
77
  if (storedNs !== attrNs) {
147
- fancyLog.info(
148
- `${attrName} namespace appeared multiple times with different value. Keeping the first one : "${storedNs}".\nEach namespace must be unique across files.`
149
- )
78
+ fancyLog.info(`${attrName} namespace appeared multiple times with different value. Keeping the first one : "${storedNs}".\nEach namespace must be unique across files.`)
150
79
  }
151
80
  } else {
152
81
  for (let nsName in namespaces) {
@@ -156,44 +85,34 @@ export function stacksvg (options) {
156
85
  }
157
86
  namespaces[attrName] = attrNs
158
87
  }
159
- }
160
- }
161
-
162
- const $defs = $svg.find(`defs`)
163
- if ($defs.length > 0) {
164
- $combinedDefs.append($defs.contents())
165
- $defs.remove()
166
- }
167
88
 
168
- let $groupWrap = null
169
- for (let [name, value] of Object.entries($svg.attr())) {
170
- if (!presentationAttributes.has(name)) {continue}
171
- if (!$groupWrap) {$groupWrap = $(`<g/>`)}
172
- $groupWrap.attr(name, value)
89
+ $icon.removeAttr(attrName)
90
+ }
173
91
  }
174
92
 
175
- if ($groupWrap) {
176
- $groupWrap.append($svg.contents())
177
- $icon.append($groupWrap)
178
- } else {
179
- $icon.append($svg.contents())
180
- }
181
- $combinedSvg.append($icon)
93
+ $rootSvg.append($icon)
182
94
  cb()
183
95
  }
184
96
 
185
- stream._flush = function flush (cb) {
186
- if (isEmpty) {return cb()}
187
- if ($combinedDefs.contents().length === 0) {
188
- $combinedDefs.remove()
97
+ function flush (cb) {
98
+ if (isEmpty) {
99
+ return cb()
189
100
  }
101
+
190
102
  for (let nsName in namespaces) {
191
- $combinedSvg.attr(nsName, namespaces[nsName])
103
+ $rootSvg.attr(nsName, namespaces[nsName])
192
104
  }
193
- const file = new Vinyl({ path: fileName, contents: Buffer.from($.xml()) })
105
+
106
+ output = output.endsWith(`.svg`) ? output : `${output}.svg`
107
+
108
+ const file = new Vinyl({ path: output, contents: Buffer.from($stack.xml()) })
109
+
194
110
  this.push(file)
195
111
  cb()
196
112
  }
197
113
 
114
+ stream._transform = transform
115
+ stream._flush = flush
116
+
198
117
  return stream
199
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gulp-stacksvg",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "Combine svg files into one with stack method",
6
6
  "main": "index.js",