Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: improve nuxt-content attrs handling #223

Merged
merged 2 commits into from
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions lib/templates/nuxt-content.dev.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
/>
<nuxt-content-dev
ref="content"
:class="staticClass"
:id="id"
:class="classes"
v-show="!isEditing"
:document="document"
@dblclick="toggleEdit"
Expand All @@ -28,19 +29,32 @@ export default {
props: NuxtContent.props,
data () {
return {
staticClass: [],
classes: [],
isEditing: false,
file: null
file: null,
id: null
}
},
mounted () {
if (this.$vnode.data.attrs && this.$vnode.data.attrs.id) {
this.id = this.$vnode.data.attrs.id
}
if (this.$vnode.data.class) {
this.staticClass = this.staticClass.concat(this.$vnode.data.class)
let classes
if (Array.isArray(this.$vnode.data.class)) {
classes = this.$vnode.data.class
} else if (typeof this.$vnode.data.class === 'object') {
const keys = Object.keys(this.$vnode.data.class)
classes = keys.filter(key => this.$vnode.data.class[key])
} else {
classes = this.$vnode.data.class
}
this.classes = this.classes.concat(classes)
delete this.$vnode.data.class
}

if (this.$vnode.data.staticClass) {
this.staticClass = this.staticClass.concat(this.$vnode.data.staticClass)
this.classes = this.classes.concat(this.$vnode.data.staticClass)
delete this.$vnode.data.staticClass
}
},
Expand Down
11 changes: 10 additions & 1 deletion lib/templates/nuxt-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,16 @@ export default {
if (!body || !body.children || !Array.isArray(body.children)) {
return
}
data.class = (data.class || []).concat('nuxt-content')
let classes = []
if (Array.isArray(data.class)) {
classes = data.class
} else if (typeof data.class === 'object') {
const keys = Object.keys(data.class)
classes = keys.filter(key => data.class[key])
} else {
classes = [data.class]
}
data.class = classes.concat('nuxt-content')
data.props = Object.assign({ ...body.props }, data.props)
return h('div', data, body.children.map((child) => processNode(child, h, document)))
}
Expand Down
87 changes: 68 additions & 19 deletions test/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,78 @@ const { setup, loadConfig, url } = require('@nuxtjs/module-test-utils')
describe('component', () => {
let nuxt, browser, page

beforeAll(async () => {
({ nuxt } = (await setup(loadConfig(__dirname))))
browser = await createBrowser('puppeteer')
}, 60000)

afterAll(async () => {
await nuxt.close()
await browser.close()
})
describe('', () => {
beforeAll(async () => {
({ nuxt } = (await setup(loadConfig(__dirname))))
browser = await createBrowser('puppeteer')
}, 60000)

afterAll(async () => {
await nuxt.close()
await browser.close()
})

test('has generated html', async () => {
page = await browser.page(url('/home'))
const html = await page.getHtml()

expect(html).toContain('<h1>Home</h1> <div class="nuxt-content"><p>This is the home page!</p></div>')
})

test('has generated html with id', async () => {
page = await browser.page(url('/home?withId=true'))
const html = await page.getHtml()

expect(html).toContain('<h1>Home</h1> <div id="my-id" class="nuxt-content"><p>This is the home page!</p></div>')
})

test('has generated html with class', async () => {
page = await browser.page(url('/home?withClass=true'))
const html = await page.getHtml()

test('nuxt-content has generated html', async () => {
page = await browser.page(url('/home'))
const html = await page.getHtml()
expect(html).toContain('<h1>Home</h1> <div class="my-class nuxt-content"><p>This is the home page!</p></div>')
})

expect(html).toContain('<h1>Home</h1> <div class="nuxt-content"><p>This is the home page!</p></div>')
test('has rendered a Vue.js component', async () => {
page = await browser.page(url('/vue-component'))
const html = await page.getHtml()

expect(html).toMatch(
new RegExp(/<div>\s*<h1><\/h1>\s*<div class="nuxt-content">\s*<div>\s*<header>Header content<\/header>\s*<main>\s*Main content\s*<\/main>\s*<footer>Footer content<\/footer><\/div><\/div><\/div>/)
)
})
})

test('nuxt-content has rendered a Vue.js component', async () => {
page = await browser.page(url('/vue-component'))
const html = await page.getHtml()
describe('in dev mode', () => {
beforeAll(async () => {
({ nuxt } = (await setup({ ...loadConfig(__dirname), content: { watch: true } })))
browser = await createBrowser('puppeteer')
}, 60000)

afterAll(async () => {
await nuxt.close()
await browser.close()
})

test('has generated html', async () => {
page = await browser.page(url('/home'))
const html = await page.getHtml()

expect(html).toMatch(/<div><h1>.*<\/h1>\s*<div\s*.*class="nuxt-content-container"\s*.*><textarea.*><\/textarea>\s*<div\s*.*class="nuxt-content"\s*.*><p.*>This is the home page!<\/p><\/div><\/div><\/div>/)
})

test('has generated html with id', async () => {
page = await browser.page(url('/home?withId=true'))
const html = await page.getHtml()

expect(html).toMatch(/<div><h1>.*<\/h1>\s*<div\s*.*id="my-id"\s*class="nuxt-content-container"\s*.*><textarea.*><\/textarea>\s*<div\s*.*class="nuxt-content"\s*.*id="my-id"\s*.*><p.*>This is the home page!<\/p><\/div><\/div><\/div>/)
})

test('has generated html with class', async () => {
page = await browser.page(url('/home?withClass=true'))
const html = await page.getHtml()

expect(html).toMatch(
new RegExp(/<div>\s*<h1><\/h1>\s*<div class="nuxt-content">\s*<div>\s*<header>Header content<\/header>\s*<main>\s*Main content\s*<\/main>\s*<footer>Footer content<\/footer><\/div><\/div><\/div>/)
)
expect(html).toMatch(/<div><h1>.*<\/h1>\s*<div\s*.*class="nuxt-content-container"\s*.*><textarea.*><\/textarea>\s*<div\s*.*class="my-class nuxt-content"\s*.*><p.*>This is the home page!<\/p><\/div><\/div><\/div>/)
})
})
})
11 changes: 8 additions & 3 deletions test/fixture/pages/_slug.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div>
<h1>{{ page.title }}</h1>
<nuxt-content :document="page" />
<nuxt-content :id="id" :document="page" :class="classes" />
</div>
</template>

Expand All @@ -12,11 +12,16 @@ export default {
components: {
AppLayout // eslint-disable-line vue/no-unused-components
},
async asyncData ({ $content, params }) {
async asyncData ({ $content, params, query }) {
const id = query.withId ? 'my-id' : undefined
const classes = query.withClass ? 'my-class' : undefined

const page = await $content(params.slug || 'home').fetch()

return {
page
page,
id,
classes
}
}
}
Expand Down