diff --git a/docs/content/en/configuration.md b/docs/content/en/configuration.md
index be414ca3d..10b9ed8fa 100644
--- a/docs/content/en/configuration.md
+++ b/docs/content/en/configuration.md
@@ -328,7 +328,7 @@ To add your custom parser write a function that gets as an argument the content
**Example**
-```
+```js{}[nuxt.config.js]
const parseTxt = file => file.split('\n').map(line => line.trim())
// in Config:
@@ -340,11 +340,33 @@ const parseTxt = file => file.split('\n').map(line => line.trim())
}
```
+### `editor`
+
+You can provide a custom editor for editing your markdown files in development. Set the `editor` option to a path to your editor component. The code of the default editor you can find [here](https://github.com/nuxt/content/blob/master/packages/content/templates/editor.vue).
+
+
+```js{}[nuxt.config.js]
+content: {
+ editor: '~/path/to/editor/component.vue'
+}
+```
+
+Your component should implement the following:
+
+1. `v-model` for getting the markdown code.
+2. prop `isEditing` is a boolean with the information if the editing is started and the component is shown. (this is optional)
+3. when finished editing your component has to emit `endEdit`
+
+
+You should be aware that you get the full markdown file content so this includes the front-matter. You can use `gray-matter` to split and join the markdown and the front-matter.
+
+
## Defaults
```js{}[nuxt.config.js]
export default {
content: {
+ editor: '~/.nuxt/content/editor.vue',
apiPrefix: '_content',
dir: 'content',
fullTextSearchFields: ['title', 'description', 'slug', 'text'],
diff --git a/packages/content/lib/index.js b/packages/content/lib/index.js
index bf691784b..adbda8fa6 100644
--- a/packages/content/lib/index.js
+++ b/packages/content/lib/index.js
@@ -208,9 +208,15 @@ module.exports = async function (moduleOptions) {
fileName: 'content/nuxt-content.dev.vue',
src: join(__dirname, '../templates/nuxt-content.dev.vue'),
options: {
- apiPrefix: options.apiPrefixWithBase
+ apiPrefix: options.apiPrefixWithBase,
+ editor: options.editor
}
})
+ // Add dev editor component
+ this.addTemplate({
+ fileName: 'content/editor.vue',
+ src: join(__dirname, '..', 'templates', 'editor.vue')
+ })
}
function isUrl (string) {
diff --git a/packages/content/lib/utils.js b/packages/content/lib/utils.js
index 0f71139b7..d0770aa9d 100644
--- a/packages/content/lib/utils.js
+++ b/packages/content/lib/utils.js
@@ -2,6 +2,7 @@ const logger = require('consola').withScope('@nuxt/content')
const { camelCase } = require('change-case')
const getDefaults = ({ dev = false } = {}) => ({
+ editor: './editor.vue',
watch: dev,
liveEdit: true,
apiPrefix: '_content',
diff --git a/packages/content/templates/editor.vue b/packages/content/templates/editor.vue
new file mode 100644
index 000000000..18c7f350d
--- /dev/null
+++ b/packages/content/templates/editor.vue
@@ -0,0 +1,61 @@
+
+
+
+
diff --git a/packages/content/templates/nuxt-content.dev.vue b/packages/content/templates/nuxt-content.dev.vue
index c5b6b07b1..0446c8f2f 100644
--- a/packages/content/templates/nuxt-content.dev.vue
+++ b/packages/content/templates/nuxt-content.dev.vue
@@ -1,15 +1,14 @@
-
+
+
+
import NuxtContent from './nuxt-content'
+import Editor from '<%= options.editor %>';
export default {
name: 'NuxtContent',
components: {
- NuxtContentDev: NuxtContent
+ NuxtContentDev: NuxtContent,
+ Editor
},
props: NuxtContent.props,
data () {
@@ -73,18 +74,10 @@ export default {
this.isEditing = false
return
}
- // Start editing mode
- const contentHeight = this.$refs.content.offsetHeight
- const actualScrollY = window.scrollY
// Fetch file content
await this.fetchFile()
+ // Start editing mode
this.isEditing = true
- this.$refs.textarea.style.minHeight = `${contentHeight}px`
- await this.waitFor(10)
- this.$refs.textarea.focus()
- this.onType()
- await this.waitFor(10)
- window.scrollTo(window.scrollX, actualScrollY)
},
async fetchFile () {
this.file = await fetch(this.fileUrl).then(res => res.text())
@@ -94,31 +87,6 @@ export default {
},
waitFor (ms) {
return new Promise(resolve => setTimeout(resolve, ms))
- },
- onType () {
- const el = this.$refs.textarea
-
- el.style.height = el.scrollHeight + 'px'
- },
- onTabRight (event) {
- let text = this.file,
- originalSelectionStart = event.target.selectionStart,
- textStart = text.slice(0, originalSelectionStart),
- textEnd = text.slice(originalSelectionStart)
-
- this.file = `${textStart}\t${textEnd}`
- event.target.value = this.file // required to make the cursor stay in place.
- event.target.selectionEnd = event.target.selectionStart = originalSelectionStart + 1
- },
- onTabLeft (event) {
- let text = this.file,
- originalSelectionStart = event.target.selectionStart,
- textStart = text.slice(0, originalSelectionStart),
- textEnd = text.slice(originalSelectionStart)
-
- this.file = `${textStart.replace(/\t$/, '')}${textEnd}`
- event.target.value = this.file // required to make the cursor stay in place.
- event.target.selectionEnd = event.target.selectionStart = originalSelectionStart - 1
}
}
}
diff --git a/test/editor.test.js b/test/editor.test.js
new file mode 100644
index 000000000..119b9ab45
--- /dev/null
+++ b/test/editor.test.js
@@ -0,0 +1,62 @@
+const path = require('path')
+const { createBrowser } = require('tib')
+const { setup, loadConfig, url } = require('@nuxtjs/module-test-utils')
+
+describe('editor option', () => {
+ let nuxt, browser, page
+
+ describe('alias works', () => {
+ test('lokal alias', async () => {
+ ({ nuxt } = (await setup({
+ ...loadConfig(__dirname),
+ buildDir: path.join(__dirname, 'fixture', '.nuxt-dev'),
+ content: { watch: true, editor: '~/.nuxt-dev/content/editor.vue' }
+ })))
+
+ browser = await createBrowser('puppeteer')
+ page = await browser.page(url('/home'))
+ const html = await page.getHtml()
+
+ expect(html).toMatch(/.*<\/h1>\s*<\/textarea>\s*This is the home page!<\/p><\/div><\/div><\/div>/)
+
+ await nuxt.close()
+ await browser.close()
+ }, 60000)
+
+ test('module resolution', async () => {
+ ({ nuxt } = (await setup({
+ ...loadConfig(__dirname),
+ buildDir: path.join(__dirname, 'fixture', '.nuxt-dev'),
+ content: { watch: true, editor: '@nuxt/content/templates/editor.vue' }
+ })))
+
+ browser = await createBrowser('puppeteer')
+ page = await browser.page(url('/home'))
+ const html = await page.getHtml()
+
+ expect(html).toMatch(/.*<\/h1>\s*<\/textarea>\s*This is the home page!<\/p><\/div><\/div><\/div>/)
+
+ await nuxt.close()
+ await browser.close()
+ }, 60000)
+ })
+
+ describe('replacing works', () => {
+ test('replacing', async () => {
+ ({ nuxt } = (await setup({
+ ...loadConfig(__dirname),
+ buildDir: path.join(__dirname, 'fixture', '.nuxt-dev'),
+ content: { watch: true, editor: '~/components/editor.vue' }
+ })))
+
+ browser = await createBrowser('puppeteer')
+ page = await browser.page(url('/home'))
+ const html = await page.getHtml()
+
+ expect(html).toMatch(/.*<\/h1>\s*<\/div>\s*
This is the home page!<\/p><\/div><\/div><\/div>/)
+
+ await nuxt.close()
+ await browser.close()
+ }, 60000)
+ })
+})
diff --git a/test/fixture/components/editor.vue b/test/fixture/components/editor.vue
new file mode 100644
index 000000000..44243fbe9
--- /dev/null
+++ b/test/fixture/components/editor.vue
@@ -0,0 +1,3 @@
+
+
+