Skip to content
This repository was archived by the owner on Aug 9, 2023. It is now read-only.

Commit 9ba30f0

Browse files
wooormmedfreeman
andauthored
Add support for Vue
Closes GH-7. Closes GH-15. Closes GH-17. Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com> Co-authored-by: Mehdi Lahlou <mehdi.lahlou@free.fr>
1 parent b5daafe commit 9ba30f0

File tree

3 files changed

+137
-10
lines changed

3 files changed

+137
-10
lines changed

index.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function wrapper(h, node, options) {
1818
var prefix
1919
var r
2020
var v
21+
var vd
2122

2223
if (typeof h !== 'function') {
2324
throw new Error('h is not a function')
@@ -31,10 +32,11 @@ function wrapper(h, node, options) {
3132
}
3233

3334
r = react(h)
34-
v = vdom(h)
35+
v = vue(h)
36+
vd = vdom(h)
3537

3638
if (prefix === null || prefix === undefined) {
37-
prefix = r === true || v === true ? 'h-' : false
39+
prefix = r === true || v === true || vd === true ? 'h-' : false
3840
}
3941

4042
if (is('root', node)) {
@@ -59,7 +61,8 @@ function wrapper(h, node, options) {
5961
prefix: prefix,
6062
key: 0,
6163
react: r,
62-
vdom: v,
64+
vue: v,
65+
vdom: vd,
6366
hyperscript: hyperscript(h)
6467
})
6568
}
@@ -98,9 +101,9 @@ function toH(h, node, ctx) {
98101

99102
if (
100103
typeof attributes.style === 'string' &&
101-
(ctx.vdom === true || ctx.react === true)
104+
(ctx.vdom === true || ctx.vue === true || ctx.react === true)
102105
) {
103-
// VDOM and React accept `style` as object.
106+
// VDOM, Vue, and React accept `style` as object.
104107
attributes.style = parseStyle(attributes.style, name)
105108
}
106109

@@ -140,7 +143,7 @@ function toH(h, node, ctx) {
140143
}
141144

142145
function addAttribute(props, prop, value, ctx) {
143-
var hyperlike = ctx.hyperscript || ctx.vdom
146+
var hyperlike = ctx.hyperscript || ctx.vdom || ctx.vue
144147
var schema = ctx.schema
145148
var info = find(schema, prop)
146149
var subprop
@@ -167,7 +170,11 @@ function addAttribute(props, prop, value, ctx) {
167170
value = ''
168171
}
169172

170-
if (!info.mustUseProperty) {
173+
if (ctx.vue) {
174+
if (prop !== 'style') {
175+
subprop = 'attrs'
176+
}
177+
} else if (!info.mustUseProperty) {
171178
if (ctx.vdom === true) {
172179
subprop = 'attributes'
173180
} else if (ctx.hyperscript === true) {
@@ -204,6 +211,11 @@ function vdom(h) {
204211
return h && h('div').type === 'VirtualNode'
205212
}
206213

214+
function vue(h) {
215+
var node = h && h('div')
216+
return Boolean(node && node.context && node.context._isVue)
217+
}
218+
207219
function parseStyle(value, tagName) {
208220
var result = {}
209221

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
"unist-builder": "^1.0.1",
4848
"vdom-to-html": "^2.3.1",
4949
"virtual-dom": "^2.1.1",
50+
"vue": "^2.6.10",
51+
"vue-server-renderer": "^2.6.10",
5052
"xo": "^0.24.0"
5153
},
5254
"scripts": {

test.js

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ var r = require('react').createElement
1010
var rehype = require('rehype')
1111
var vToString = require('vdom-to-html')
1212
var rToString = require('react-dom/server').renderToStaticMarkup
13+
var Vue = require('vue')
14+
var VueSSR = require('vue-server-renderer')
1315
var toH = require('.')
1416

1517
var processor = rehype().data('settings', {fragment: true, position: false})
@@ -386,6 +388,119 @@ test('hast-to-hyperscript', function(t) {
386388
st.end()
387389
})
388390

391+
t.test('should support `Vue`', function(st) {
392+
var baseline = doc.replace(/<div>/, '<div data-server-rendered="true">')
393+
var actual
394+
var expected
395+
396+
st.plan(3)
397+
398+
Promise.all([vueToString(actualRender), vueToString(expectedRender)])
399+
.then(function(all) {
400+
var actualString = all[0]
401+
var expectedString = all[0]
402+
403+
st.deepEqual(clean(actual), clean(expected), 'equal syntax trees')
404+
st.deepEqual(html(actualString), html(baseline), 'equal output')
405+
406+
st.deepEqual(
407+
html(expectedString),
408+
html(baseline),
409+
'equal output baseline'
410+
)
411+
})
412+
.catch(function(error) {
413+
st.ifErr(error, 'did not expect an error')
414+
})
415+
416+
function actualRender(h) {
417+
actual = toH(h, hast)
418+
return actual
419+
}
420+
421+
function expectedRender(h) {
422+
expected = h(
423+
'div',
424+
{key: 'h-1', attrs: {'data-server-rendered': 'true'}},
425+
[
426+
h(
427+
'h1',
428+
{
429+
key: 'h-2',
430+
attrs: {
431+
class: 'b c',
432+
id: 'a',
433+
hidden: true,
434+
height: 2
435+
}
436+
},
437+
[
438+
'bravo ',
439+
h(
440+
'strong',
441+
{
442+
key: 'h-3',
443+
style: {color: 'red'},
444+
attrs: {
445+
foo: 'bar',
446+
camelCase: 'on off',
447+
'data-123': '456',
448+
'data-some': 'yes',
449+
'aria-valuenow': '1'
450+
}
451+
},
452+
['charlie']
453+
),
454+
' delta',
455+
h('input', {
456+
key: 'h-4',
457+
attrs: {
458+
checked: true,
459+
type: 'file',
460+
accept: '.jpg, .jpeg'
461+
}
462+
})
463+
]
464+
),
465+
h(
466+
'svg',
467+
{
468+
key: 'h-5',
469+
attrs: {
470+
xmlns: 'http://www.w3.org/2000/svg',
471+
viewBox: '0 0 500 500'
472+
}
473+
},
474+
[h('circle', {key: 'h-6', attrs: {cx: 120, cy: 120, r: 100}})]
475+
)
476+
]
477+
)
478+
return expected
479+
}
480+
481+
function identity(value) {
482+
return value
483+
}
484+
485+
function vueToString(render) {
486+
return VueSSR.createRenderer({template: identity}).renderToString(
487+
new Vue({render: render}).$mount()
488+
)
489+
}
490+
491+
function clean(node) {
492+
remove(node)
493+
return json(node)
494+
}
495+
496+
function remove(node) {
497+
delete node.context
498+
if (node.children) {
499+
node.children.forEach(remove)
500+
}
501+
}
502+
})
503+
389504
t.test('should support keys', function(st) {
390505
st.equal(
391506
toH(h, u('element', {tagName: 'div'})).key,
@@ -508,9 +623,7 @@ test('hast-to-hyperscript', function(t) {
508623
st.end()
509624
})
510625

511-
t.test('flattens a `root` with one element child to that child', function(
512-
st
513-
) {
626+
t.test('flattens a `root` with one element to that child', function(st) {
514627
var actual = toH(
515628
h,
516629
u('root', [u('element', {tagName: 'h1', properties: {id: 'a'}}, [])])

0 commit comments

Comments
 (0)