Skip to content

Commit

Permalink
perf: close #16, use v-html to render code at runtime in DemoAndCode.…
Browse files Browse the repository at this point in the history
…vue (#18)
  • Loading branch information
BuptStEve authored Nov 21, 2019
1 parent 4a26f4d commit 0b521d3
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 73 deletions.
2 changes: 1 addition & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
presets: [
[
'@babel/preset-env',
{ targets: { 'node': 'current' } },
{ targets: { node: 'current' } },
],
],
},
Expand Down
4 changes: 2 additions & 2 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ module.exports = {
},
},
head: [
['link', { rel: 'icon', href: `/favicon.ico` }],
['link', { rel: 'stylesheet', href: `https://unpkg.com/[email protected]/animate.min.css` }],
['link', { rel: 'icon', href: '/favicon.ico' }],
['link', { rel: 'stylesheet', href: 'https://unpkg.com/[email protected]/animate.min.css' }],
],
plugins: [
['smooth-scroll'],
Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
'!src/highlight.js',
'!src/enhanceAppFile.js',
],
coveragePathIgnorePatterns: [ '/__snapshots__/' ],
coveragePathIgnorePatterns: ['/__snapshots__/'],
transform: {
'^.+\\.vue$': 'vue-jest',
'^.+\\.jsx?$': 'babel-jest',
Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vuepress-plugin-demo-code",
"version": "0.3.7",
"version": "0.4.0",
"description": "📝 Demo and code plugin for vuepress",
"main": "src/index.js",
"files": [
Expand Down Expand Up @@ -37,35 +37,35 @@
"prismjs": "^1.17.1"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/preset-env": "^7.6.3",
"@babel/core": "^7.7.2",
"@babel/preset-env": "^7.7.1",
"@commitlint/cli": "^8.2.0",
"@commitlint/config-conventional": "^8.2.0",
"@vue/test-utils": "^1.0.0-beta.29",
"all-contributors-cli": "^6.9.1",
"all-contributors-cli": "^6.11.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"codecov": "^3.6.1",
"cross-env": "^6.0.3",
"eslint": "^6.5.1",
"eslint": "^6.6.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-vue": "^2.0.2",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^5.2.3",
"eslint-plugin-vue": "^6.0.1",
"gh-pages": "^2.1.1",
"husky": "^3.0.8",
"husky": "^3.1.0",
"jest": "^24.9.0",
"jest-serializer-vue": "^2.0.2",
"jest-transform-stub": "^2.0.0",
"lint-staged": "^9.4.2",
"lint-staged": "^9.4.3",
"markdown-it-include": "^1.1.0",
"rimraf": "^3.0.0",
"vue-jest": "^3.0.5",
"vuepress": "^1.1.0",
"vuepress-plugin-smooth-scroll": "^0.0.4"
"vuepress": "^1.2.0",
"vuepress-plugin-smooth-scroll": "^0.0.7"
},
"keywords": [
"vue",
Expand Down
41 changes: 18 additions & 23 deletions src/DemoAndCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
</div>

<div class="code-wrapper" ref="codeWrapper" :style="codeWrapperStyle">
<slot name="code" />
<div
v-html="highlightCode"
:class="`language-${language}' extra-class`"
/>
</div>
</section>
</template>

<script>
import OnlineEdit from './OnlineEdit.vue'
import getHighlightCodeHtml from './highlight'
import {
JS_RE,
CSS_RE,
Expand All @@ -50,6 +54,7 @@ export default {
},
props: {
htmlStr: { type: String, default: '' },
language: { type: String, default: 'vue' },
showText: { type: String, default: 'show code' },
hideText: { type: String, default: 'hide code' },
jsLibsStr: { type: String, default: '[]' },
Expand All @@ -74,37 +79,28 @@ export default {
}
},
computed: {
// button text
controlText: (vm) => vm.isShowCode ? vm.hideText : vm.showText,
highlightCode: vm => getHighlightCodeHtml(vm.decodedHtmlStr, vm.language),
decodedHtmlStr: vm => decodeURIComponent(vm.htmlStr),
showOnlineBtns: vm => parseAndDecode(vm.onlineBtnsStr),
// icon animation
iconStyle: (vm) => ({
transform: vm.isShowCode
? 'rotate(0)'
: 'rotate(-180deg)',
transform: vm.isShowCode ? 'rotate(0)' : 'rotate(-180deg)',
}),
// button text
controlText: (vm) => vm.isShowCode
? vm.hideText
: vm.showText,
// animation
codeWrapperStyle: (vm) => ({
'max-height': vm.isShowCode
? `${vm.codeHeight}px`
: `${vm.minHeight}px`,
'max-height': vm.isShowCode ? `${vm.codeHeight}px` : `${vm.minHeight}px`,
}),
// sticky
codeControlStyle: (vm) => ({
top: vm.isShowCode
? `${vm.navbarHeight}px`
: '0',
cursor: vm.isShowControl
? 'pointer'
: 'auto',
top: vm.isShowCode ? `${vm.navbarHeight}px` : '0',
cursor: vm.isShowControl ? 'pointer' : 'auto',
}),
parsedCode: (vm) => {
const source = decodeURIComponent(vm.htmlStr)
const js = getMatchedResult(JS_RE)(source) || ''
const css = getMatchedResult(CSS_RE)(source) || ''
const html = getMatchedResult(HTML_RE)(source) || source
const js = getMatchedResult(JS_RE)(vm.decodedHtmlStr) || ''
const css = getMatchedResult(CSS_RE)(vm.decodedHtmlStr) || ''
const html = getMatchedResult(HTML_RE)(vm.decodedHtmlStr) || vm.decodedHtmlStr
.replace(JS_RE, '')
.replace(CSS_RE, '')
.replace(HTML_RE, '')
Expand All @@ -116,7 +112,6 @@ export default {
return { js, css, html, jsLibs, cssLibs, codesandboxOptions }
},
showOnlineBtns: vm => parseAndDecode(vm.onlineBtnsStr),
},
methods: {
onClickControl () {
Expand Down
2 changes: 1 addition & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ new Vue({
components: { App },
})`

const CODE_SANDBOX_HTML = `\n<div id="app"></div>`
const CODE_SANDBOX_HTML = '\n<div id="app"></div>'

module.exports = {
JS_RE,
Expand Down
46 changes: 25 additions & 21 deletions src/highlight.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// copy from https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/markdown/lib/highlight.js
// https://github.com/vuejs/vuepress/blob/master/packages/@vuepress/markdown/lib/highlight.js

const prism = require('prismjs')
const escapeHtml = require('escape-html')
const loadLanguages = require('prismjs/components/index')
const {
logger,
chalk,
escapeHtml,
} = require('@vuepress/shared-utils')

// required to make embedded highlighting work...
loadLanguages(['markup', 'css', 'javascript'])
// loadLanguages(['markup', 'css', 'javascript'])

function wrap (code, lang) {
if (lang === 'text') {
Expand All @@ -18,29 +13,38 @@ function wrap (code, lang) {
return `<pre v-pre class="language-${lang}"><code>${code}</code></pre>`
}

function getLangCodeFromExtension (extension) {
const extensionMap = {
vue: 'markup',
html: 'markup',
md: 'markdown',
rb: 'ruby',
ts: 'typescript',
py: 'python',
sh: 'bash',
yml: 'yaml',
styl: 'stylus',
kt: 'kotlin',
rs: 'rust',
}

return extensionMap[extension] || extension
}

module.exports = (str, lang) => {
if (!lang) {
return wrap(str, 'text')
}
lang = lang.toLowerCase()
const rawLang = lang
if (lang === 'vue' || lang === 'html') {
lang = 'markup'
}
if (lang === 'md') {
lang = 'markdown'
}
if (lang === 'ts') {
lang = 'typescript'
}
if (lang === 'py') {
lang = 'python'
}

lang = getLangCodeFromExtension(lang)

if (!prism.languages[lang]) {
try {
loadLanguages([lang])
} catch (e) {
logger.warn(chalk.yellow(`[vuepress] Syntax highlight for language "${lang}" is not supported.`))
console.warn(`[vuepress] Syntax highlight for language "${lang}" is not supported.`)
}
}
if (prism.languages[lang]) {
Expand Down
10 changes: 2 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const path = require('path')
const getHighlightCodeHtml = require('./highlight')
const { encodeAndStringify } = require('./utils')
const markdownItContainer = require('markdown-it-container')
const { encodeAndStringify } = require('./utils')

const defaults = {
onlineBtns: {
Expand Down Expand Up @@ -81,6 +80,7 @@ module.exports = (options = {}) => {
return `
<DemoAndCode
htmlStr="${encodeURIComponent(htmlStr)}"
language="${language}"
showText="${showText}"
hideText="${hideText}"
jsLibsStr="${jsLibsStr}"
Expand All @@ -89,12 +89,6 @@ module.exports = (options = {}) => {
onlineBtnsStr="${onlineBtnsStr}"
codesandboxStr="${codesandboxStr}"
>
<template slot="code">
<div class="language-${language} extra-class">
${getHighlightCodeHtml(htmlStr, language)}
</div>
</template>
<template slot="demo">
`
}
Expand Down
13 changes: 12 additions & 1 deletion test/__snapshots__/DemoAndCode.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ exports[`DemoAndCode should be rendered 1`] = `
<div
class="code-wrapper"
style="max-height: 200px;"
/>
>
<div
class="language-vue' extra-class"
>
<pre
class="language-vue"
v-pre=""
>
<code />
</pre>
</div>
</div>
</section>
`;
10 changes: 5 additions & 5 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ import {

describe('utils', () => {
it('getJsTmpl', () => {
const code = ` export default { data: () => ({}) }\n\n\n`
const result = getJsResult(`data: () => ({})`)
const code = ' export default { data: () => ({}) }\n\n\n'
const result = getJsResult('data: () => ({})')

expect(getJsTmpl(``)).toBe(getJsResult(``))
expect(getJsTmpl('')).toBe(getJsResult(''))
expect(getJsTmpl(code)).toBe(result)
})

it('getMatchedResult', () => {
const re = /export default {(.*)}/
const code = ` export default { data: () => ({}) }\n\n\n`
const code = ' export default { data: () => ({}) }\n\n\n'
const result = getMatchedResult(re)(code)

expect(result).toBe(`data: () => ({})`)
expect(result).toBe('data: () => ({})')
})

it('parseAndDecode and encodeAndStringify', () => {
Expand Down

0 comments on commit 0b521d3

Please sign in to comment.