From be5326e51e4a69b19e5cd5cfee3f03fca1563eee Mon Sep 17 00:00:00 2001 From: Giulio Ambrogi Date: Fri, 27 Dec 2019 14:36:15 +0000 Subject: [PATCH 01/12] UPDATE .eslintrc --- .eslintrc | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index a8f7cd0c9..7538e9d2d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,7 +1,10 @@ { "extends": "xo-space/browser", "rules": { - "semi": [2, "never"], + "semi": [ + 2, + "never" + ], "no-return-assign": "off", "no-unused-expressions": "off", "no-new-func": "off", @@ -10,11 +13,21 @@ "max-params": "off", "no-script-url": "off", "camelcase": "off", - "no-warning-comments": "off" + "object-curly-spacing": "off", + "no-warning-comments": "off", + "no-negated-condition": "off", + "eqeqeq": "warn", + "no-eq-null": "warn", + "max-statements-per-line": "warn" }, "globals": { "Docsify": true, "$docsify": true, "process": true + }, + "env": { + "browser": true, + "amd": true, + "node": true } -} +} \ No newline at end of file From fc23505c31005b49c83b003f46717f7386532a2e Mon Sep 17 00:00:00 2001 From: Giulio Ambrogi Date: Fri, 27 Dec 2019 14:36:37 +0000 Subject: [PATCH 02/12] UPDATE lint task --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 9c0197143..c29c8dfff 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "serve:ssr": "cross-env SSR=1 node server", "dev": "run-p serve watch:*", "dev:ssr": "run-p serve:ssr watch:*", - "lint": "eslint {src,packages} --fix", + "lint": "eslint . --fix", "test": "mocha test/*/**", "css": "node build/css", "watch:css": "npm run css -- -o themes -w", @@ -48,8 +48,8 @@ }, "lint-staged": { "*.js": [ - "npm run lint", - "git add" + "npm run lint", + "git add" ] }, "dependencies": { @@ -98,4 +98,4 @@ "collective": { "url": "https://opencollective.com/docsify" } -} +} \ No newline at end of file From bb1faff24ff38bebf7bb58485670e2d408ccf9e5 Mon Sep 17 00:00:00 2001 From: Giulio Ambrogi Date: Fri, 27 Dec 2019 14:52:20 +0000 Subject: [PATCH 03/12] FIX lint errors --- .eslintrc | 3 +- docs/_media/example.js | 10 +- packages/docsify-server-renderer/index.js | 3 + src/core/config.js | 8 +- src/core/event/scroll.js | 7 ++ src/core/event/sidebar.js | 4 + src/core/fetch/ajax.js | 2 + src/core/fetch/index.js | 4 + src/core/render/compiler.js | 14 +++ src/core/render/embed.js | 28 ++--- src/core/render/gen-tree.js | 2 + src/core/render/index.js | 8 ++ src/core/render/progressbar.js | 1 + src/core/render/tpl.js | 12 +- src/core/router/history/base.js | 1 + src/core/router/history/hash.js | 1 + src/core/router/util.js | 18 ++- src/core/util/core.js | 4 +- src/core/util/dom.js | 2 + src/plugins/ga.js | 1 + src/plugins/matomo.js | 7 +- src/plugins/search/component.js | 3 + src/plugins/search/search.js | 10 +- test/_helper.js | 129 +++++++++++----------- test/integration/render.js | 21 ++-- test/integration/router.js | 21 ++-- test/unit/base.js | 123 ++++++++++----------- test/unit/render.js | 73 ++++++------ test/unit/util.js | 59 +++++----- 29 files changed, 321 insertions(+), 258 deletions(-) diff --git a/.eslintrc b/.eslintrc index 7538e9d2d..2bc6db86c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -28,6 +28,7 @@ "env": { "browser": true, "amd": true, - "node": true + "node": true, + "mocha": true } } \ No newline at end of file diff --git a/docs/_media/example.js b/docs/_media/example.js index 7b6f668cc..8cad2d730 100644 --- a/docs/_media/example.js +++ b/docs/_media/example.js @@ -5,12 +5,12 @@ const PORT = 8080 /// [demo] const result = fetch(`${URL}:${PORT}`) - .then(function(response) { - return response.json(); + .then(function (response) { + return response.json() + }) + .then(function (myJson) { + console.log(JSON.stringify(myJson)) }) - .then(function(myJson) { - console.log(JSON.stringify(myJson)); - }); /// [demo] result.then(console.log).catch(console.error) diff --git a/packages/docsify-server-renderer/index.js b/packages/docsify-server-renderer/index.js index 21fb5c797..5b62effee 100644 --- a/packages/docsify-server-renderer/index.js +++ b/packages/docsify-server-renderer/index.js @@ -21,6 +21,7 @@ function mainTpl(config) { if (config.repo) { html += tpl.corner(config.repo) } + if (config.coverpage) { html += tpl.cover() } @@ -154,12 +155,14 @@ export default class Renderer { if (!res.ok) { throw Error() } + content = await res.text() this.lock = 0 } else { content = await readFileSync(filePath, 'utf8') this.lock = 0 } + return content } catch (e) { this.lock = this.lock || 0 diff --git a/src/core/config.js b/src/core/config.js index f77773726..9a3251e72 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -23,9 +23,9 @@ export default function () { ext: '.md', mergeNavbar: false, formatUpdated: '', - // this config for the links inside markdown + // This config for the links inside markdown externalLinkTarget: '_blank', - // this config for the corner + // This config for the corner cornerExternalLinkTarget: '_blank', externalLinkRel: 'noopener', routerMode: 'hash', @@ -55,15 +55,19 @@ export default function () { if (config.loadSidebar === true) { config.loadSidebar = '_sidebar' + config.ext } + if (config.loadNavbar === true) { config.loadNavbar = '_navbar' + config.ext } + if (config.coverpage === true) { config.coverpage = '_coverpage' + config.ext } + if (config.repo === true) { config.repo = '' } + if (config.name === true) { config.name = '' } diff --git a/src/core/event/scroll.js b/src/core/event/scroll.js index 3e9e33265..11b0cdd78 100644 --- a/src/core/event/scroll.js +++ b/src/core/event/scroll.js @@ -12,6 +12,7 @@ function scrollTo(el) { if (scroller) { scroller.stop() } + enableScrollEvent = false scroller = new Tweezer({ start: window.pageYOffset, @@ -30,6 +31,7 @@ function highlight(path) { if (!enableScrollEvent) { return } + const sidebar = dom.getNode('.sidebar') const anchors = dom.findAll('.anchor') const wrap = dom.find(sidebar, '.sidebar-nav') @@ -45,14 +47,17 @@ function highlight(path) { if (!last) { last = node } + break } else { last = node } } + if (!last) { return } + const li = nav[getNavKey(decodeURIComponent(path), last.getAttribute('data-id'))] if (!li || li === active) { @@ -98,6 +103,7 @@ export function scrollActiveSidebar(router) { if (!a) { continue } + let href = a.getAttribute('href') if (href !== '/') { @@ -115,6 +121,7 @@ export function scrollActiveSidebar(router) { if (isMobile) { return } + const path = router.getCurrentPath() dom.off('scroll', () => highlight(path)) dom.on('scroll', () => highlight(path)) diff --git a/src/core/event/sidebar.js b/src/core/event/sidebar.js index 81c3003f5..cd3900881 100644 --- a/src/core/event/sidebar.js +++ b/src/core/event/sidebar.js @@ -12,6 +12,7 @@ export function btn(el) { if (el == null) { return } + dom.on(el, 'click', e => { e.stopPropagation() toggle() @@ -30,6 +31,7 @@ export function collapse(el) { if (el == null) { return } + dom.on(el, 'click', ({target}) => { if ( target.nodeName === 'A' && @@ -46,6 +48,7 @@ export function sticky() { if (!cover) { return } + const coverHeight = cover.getBoundingClientRect().height if (window.pageYOffset >= coverHeight || cover.classList.contains('hidden')) { @@ -69,6 +72,7 @@ export function getAndActive(router, el, isParent, autoTitle) { if (el != null) { links = dom.findAll(el, 'a') } + const hash = decodeURI(router.toURL(router.getCurrentPath())) let target diff --git a/src/core/fetch/ajax.js b/src/core/fetch/ajax.js index 5911b7994..7a8ab5536 100644 --- a/src/core/fetch/ajax.js +++ b/src/core/fetch/ajax.js @@ -14,6 +14,7 @@ export function get(url, hasBar = false, headers = {}) { const on = function () { xhr.addEventListener.apply(xhr, arguments) } + const cached = cache[url] if (cached) { @@ -26,6 +27,7 @@ export function get(url, hasBar = false, headers = {}) { xhr.setRequestHeader(i, headers[i]) } } + xhr.send() return { diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index 17208df69..ee21abbe2 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -140,6 +140,7 @@ export function fetchMixin(proto) { } else { this._renderCover(null, coverOnly) } + return coverOnly } } @@ -174,6 +175,7 @@ export function fetchMixin(proto) { if (fallbackLanguages.indexOf(local) === -1) { return false } + const newPath = path.replace(new RegExp(`^/${local}`), '') const req = request(newPath + qs, true, requestHeaders) @@ -189,6 +191,7 @@ export function fetchMixin(proto) { return true } + /** * Load the 404 page * @param path @@ -225,6 +228,7 @@ export function initFetch(vm) { if (loadSidebar && activeEl) { activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__ } + vm._bindEventOnRendered(activeEl) vm.$resetEvents() callHook(vm, 'doneEach') diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index 2f7ce1528..ac447e007 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -162,9 +162,11 @@ export class Compiler { } else if (/\.mp3/.test(href)) { type = 'audio' } + embed = compileMedia[type].call(this, href, title) embed.type = type } + embed.fragment = config.fragment return embed @@ -217,6 +219,7 @@ export class Compiler { return `${str}` } + // Highlight code origin.code = renderer.code = function (code, lang = '') { code = code.replace(/@DOCSIFY_QM@/g, '`') @@ -227,6 +230,7 @@ export class Compiler { return `
${hl}
` } + origin.link = renderer.link = function (href, title = '', text) { let attrs = '' @@ -241,6 +245,7 @@ export class Compiler { if (href === _self.config.homepage) { href = 'README' } + href = router.toURL(href, null, router.getCurrentPath()) } else { attrs += href.indexOf('mailto:') === 0 ? '' : ` target="${linkTarget}"` @@ -262,6 +267,7 @@ export class Compiler { return `${text}` } + origin.paragraph = renderer.paragraph = function (text) { let result if (/^!>/.test(text)) { @@ -271,8 +277,10 @@ export class Compiler { } else { result = `

${text}

` } + return result } + origin.image = renderer.image = function (href, title, text) { let url = href let attrs = '' @@ -304,6 +312,7 @@ export class Compiler { return `${text}` } + origin.list = renderer.list = function (body, ordered, start) { const isTaskList = /
  • /.test(body.split('class="task-list"')[0]) const isStartReq = start && start > 1 @@ -315,6 +324,7 @@ export class Compiler { return `<${tag} ${tagAttrs}>${body}` } + origin.listitem = renderer.listitem = function (text) { const isTaskItem = /^(]*>)/.test(text) const html = isTaskItem ? `
  • ` : `
  • ${text}
  • ` @@ -346,9 +356,11 @@ export class Compiler { for (let j = i; deletedHeaderLevel < toc[j].level && j < toc.length; j++) { toc.splice(j, 1) && j-- && i++ } + i-- } } + const tree = this.cacheTree[currentPath] || genTree(toc, level) html = treeTpl(tree, '
      {inner}
    ') this.cacheTree[currentPath] = tree @@ -365,6 +377,7 @@ export class Compiler { this.toc = [] return } + const currentPath = this.router.getCurrentPath() const {cacheTree, toc} = this @@ -374,6 +387,7 @@ export class Compiler { for (let i = 0; i < toc.length; i++) { toc[i].ignoreSubHeading && toc.splice(i, 1) && i-- } + const tree = cacheTree[currentPath] || genTree(toc, level) cacheTree[currentPath] = tree diff --git a/src/core/render/embed.js b/src/core/render/embed.js index 821837488..eefa07bda 100644 --- a/src/core/render/embed.js +++ b/src/core/render/embed.js @@ -1,9 +1,9 @@ -import {get} from '../fetch/ajax' -import {merge} from '../util/core' +import { get } from '../fetch/ajax' +import { merge } from '../util/core' const cached = {} -function walkFetchEmbed({embedTokens, compile, fetch}, cb) { +function walkFetchEmbed({ embedTokens, compile, fetch }, cb) { let token let step = 0 let count = 1 @@ -23,26 +23,28 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) { if (token.embed.fragment) { const fragment = token.embed.fragment const pattern = new RegExp(`(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]([\\s\\S]*)(?:###|\\/\\/\\/)\\s*\\[${fragment}\\]`) - text = ((text.match(pattern) || [])[1] || '').trim() + text = ((text.match(pattern) || [])[1] || '').trim() } + embedToken = compile.lexer( '```' + - token.embed.lang + - '\n' + - text.replace(/`/g, '@DOCSIFY_QM@') + - '\n```\n' + token.embed.lang + + '\n' + + text.replace(/`/g, '@DOCSIFY_QM@') + + '\n```\n' ) } else if (token.embed.type === 'mermaid') { embedToken = [ - {type: 'html', text: `
    \n${text}\n
    `} + { type: 'html', text: `
    \n${text}\n
    ` } ] embedToken.links = {} } else { - embedToken = [{type: 'html', text}] + embedToken = [{ type: 'html', text }] embedToken.links = {} } } - cb({token, embedToken}) + + cb({ token, embedToken }) if (++count >= step) { cb({}) } @@ -61,7 +63,7 @@ function walkFetchEmbed({embedTokens, compile, fetch}, cb) { } } -export function prerenderEmbed({compiler, raw = '', fetch}, done) { +export function prerenderEmbed({ compiler, raw = '', fetch }, done) { let hit = cached[raw] if (hit) { const copy = hit.slice() @@ -96,7 +98,7 @@ export function prerenderEmbed({compiler, raw = '', fetch}, done) { }) let moveIndex = 0 - walkFetchEmbed({compile, embedTokens, fetch}, ({embedToken, token}) => { + walkFetchEmbed({ compile, embedTokens, fetch }, ({ embedToken, token }) => { if (token) { const index = token.index + moveIndex diff --git a/src/core/render/gen-tree.js b/src/core/render/gen-tree.js index 81ba4bd22..a4619eb5e 100644 --- a/src/core/render/gen-tree.js +++ b/src/core/render/gen-tree.js @@ -16,11 +16,13 @@ export function genTree(toc, maxLevel) { if (level > maxLevel) { return } + if (last[len]) { last[len].children = (last[len].children || []).concat(headline) } else { headlines.push(headline) } + last[level] = headline }) diff --git a/src/core/render/index.js b/src/core/render/index.js index b4d16006d..5df3c4cd5 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -18,6 +18,7 @@ function executeScript() { if (!script) { return false } + const code = script.innerText.trim() if (!code) { return false @@ -102,6 +103,7 @@ export function renderMixin(proto) { // Reset toc this.compiler.subSidebar() } + // Bind event this._bindEventOnRendered(activeEl) } @@ -145,6 +147,7 @@ export function renderMixin(proto) { callHook(this, 'afterEach', html, text => renderMain.call(this, text)) } + if (this.isHTML) { html = this.result = text callback() @@ -173,6 +176,7 @@ export function renderMixin(proto) { dom.toggleClass(el, 'remove', 'show') return } + dom.toggleClass(el, 'add', 'show') let html = this.coverIsHTML ? text : this.compiler.cover(text) @@ -191,10 +195,12 @@ export function renderMixin(proto) { if (!isAbsolutePath(m[1])) { path = getPath(this.router.getBasePath(), m[1]) } + el.style.backgroundImage = `url(${path})` el.style.backgroundSize = 'cover' el.style.backgroundPosition = 'center center' } + html = html.replace(m[0], '') } @@ -228,6 +234,7 @@ export function initRender(vm) { if (config.repo) { html += tpl.corner(config.repo, config.cornerExternalLinkTarge) } + if (config.coverpage) { html += tpl.cover() } @@ -271,6 +278,7 @@ export function initRender(vm) { // Polyfll cssVars(config.themeColor) } + vm._updateRender() dom.toggleClass(dom.body, 'ready') } diff --git a/src/core/render/progressbar.js b/src/core/render/progressbar.js index df1546469..61a2aae22 100644 --- a/src/core/render/progressbar.js +++ b/src/core/render/progressbar.js @@ -13,6 +13,7 @@ function init() { dom.appendTo(dom.body, div) barEl = div } + /** * Render progress bar */ diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 2b5862287..a3c54b879 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -9,11 +9,13 @@ export function corner(data, cornerExternalLinkTarge) { if (!data) { return '' } + if (!/\/\//.test(data)) { data = 'https://github.com/' + data } + data = data.replace(/^git\+/, '') - // double check + // Double check cornerExternalLinkTarge = cornerExternalLinkTarge || '_blank' return ( @@ -31,8 +33,7 @@ export function corner(data, cornerExternalLinkTarge) { * Render main content */ export function main(config) { - - const name = config.name? escapeString(config.name):'' + const name = config.name ? escapeString(config.name) : '' const aside = '