Skip to content

Commit

Permalink
use a custom style component when styles are not inlined
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Nov 10, 2018
1 parent 51bfe35 commit 4e1cb62
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 30 deletions.
34 changes: 15 additions & 19 deletions example/icon.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 40 additions & 9 deletions index.js
@@ -1,41 +1,72 @@
const path = require('path')
const posthtml = require('posthtml')

const plugin = tree => {
tree.match({ tag: 'svg' }, node => {
// Remove unnecessary attrs on SVG tag
const REGISTER_STYLE_COMPONENT = path.join(__dirname, './lib/registerStyleComponent.js')

const plugin = state => tree => {
tree.match({ tag: 'svg' }, node => {
const attrs = {}

node.attrs = node.attrs || {}
for (const name of Object.keys(node.attrs)) {
// Don't add unnecessary attrs
if (name !== 'version' && name !== 'xmlns' && !name.startsWith('xmlns:')) {
attrs[name] = node.attrs[name]
}
delete node.attrs[name]
}

// Adding v-bind
node.attrs['v-bind'] = `Object.assign(${JSON.stringify(attrs)},data.attrs)`
const hasAttrs = Object.keys(attrs).length > 0
node.attrs['v-bind'] = hasAttrs ? `Object.assign(${JSON.stringify(attrs)},data.attrs)` : 'data.attrs'

// Adding v-on
node.attrs['v-on'] = 'data.on'

return node
})

// SVGO will inline styles, so if you don't turn off relevant plugin
// the tree will never match `style` nodes because they don't exist
tree.match({ tag: 'style' }, node => {
// Ignore the style tag if it's empty
if (!node.content || node.content.length === 0) return

// When SVGO is turned off
// Make `style` tags work by using a Vue component
node.tag = 'svg2vue-style'
state.hasStyleTag = true
return node
})
}

const createComponent = svg => {
return `<template functional>${svg}</template>`
const createComponent = (svg, state) => {
let result = `<template functional>${svg}</template>`

if (state.hasStyleTag) {
result += `
<script>
import ${JSON.stringify(REGISTER_STYLE_COMPONENT)}
export default {}
</script>
`
}

return result
}

module.exports = (input, { sync } = {}) => {
const state = {}

const stream = posthtml([
plugin
plugin(state)
]).process(input, { sync })

if (stream.then) {
return stream.then(res => ({
component: createComponent(res.html)
component: createComponent(res.html, state)
}))
}

return { component: createComponent(stream.html) }
return { component: createComponent(stream.html, state) }
}
12 changes: 12 additions & 0 deletions lib/registerStyleComponent.js
@@ -0,0 +1,12 @@
import Vue from 'vue'

var NAME = 'svg2vue-style'

if (!Vue.component(NAME)) {
Vue.component(NAME, {
functional: true,
render: function (h, ctx) {
return h('style', ctx.data, ctx.children)
}
})
}
11 changes: 9 additions & 2 deletions package.json
Expand Up @@ -9,7 +9,8 @@
"main": "index.js",
"files": [
"index.js",
"loader.js"
"loader.js",
"lib"
],
"scripts": {
"test": "npm run lint && ava",
Expand Down Expand Up @@ -37,6 +38,12 @@
"xo": "^0.18.0"
},
"xo": {
"extends": "rem"
"extends": "rem",
"rules": {
"unicorn/filename": "off"
},
"ignores": [
"lib/registerStyleComponent.js"
]
}
}
6 changes: 6 additions & 0 deletions test/index.test.js
Expand Up @@ -30,3 +30,9 @@ test('main', t => {

t.snapshot(sfc)
})

test('replace style tag', t => {
const sfc = toSFC(`<svg><style>svg {width:20px;}</style></svg>`, { sync: true })

t.snapshot(sfc)
})
13 changes: 13 additions & 0 deletions test/snapshots/index.test.js.md
Expand Up @@ -32,3 +32,16 @@ Generated by [AVA](https://ava.li).
</svg>␊
</template>`,
}

## replace style tag

> Snapshot 1
{
component: `<template functional><svg v-bind="data.attrs" v-on="data.on"><svg2vue-style>svg {width:20px;}</svg2vue-style></svg></template>␊
<script>␊
import "/Users/egoist/dev/svg-to-vue-component/lib/registerStyleComponent.js"␊
export default {}␊
</script>␊
`,
}
Binary file modified test/snapshots/index.test.js.snap
Binary file not shown.

0 comments on commit 4e1cb62

Please sign in to comment.