docsify/src/core/fetch/index.js
Giulio Ambrogi db97a1d22a Eslint fixes for v4x (#989)
* UPDATE .eslintrc

* UPDATE lint task

* FIX lint errors

* CLEANUP

* FIX no-eq-null warning

* FIX many jsdoc warnings

* FIX jsdoc issues

* FIX jsdoc warnings

* FIX jsdoc

* FIX eqeq and no-eq-null

* ADD lint to travis

* UPDATE test env for eslint
2019-12-30 22:01:46 +05:30

240 lines
5.7 KiB
JavaScript

import { get } from './ajax'
import { callHook } from '../init/lifecycle'
import { getParentPath, stringifyQuery } from '../router/util'
import { noop } from '../util/core'
import { getAndActive } from '../event/sidebar'
function loadNested(path, qs, file, next, vm, first) {
path = first ? path : path.replace(/\/$/, '')
path = getParentPath(path)
if (!path) {
return
}
get(
vm.router.getFile(path + file) + qs,
false,
vm.config.requestHeaders
).then(next, _ => loadNested(path, qs, file, next, vm))
}
export function fetchMixin(proto) {
let last
const abort = () => last && last.abort && last.abort()
const request = (url, hasbar, requestHeaders) => {
abort()
last = get(url, true, requestHeaders)
return last
}
const get404Path = (path, config) => {
const { notFoundPage, ext } = config
const defaultPath = '_404' + (ext || '.md')
let key
let path404
switch (typeof notFoundPage) {
case 'boolean':
path404 = defaultPath
break
case 'string':
path404 = notFoundPage
break
case 'object':
key = Object.keys(notFoundPage)
.sort((a, b) => b.length - a.length)
.find(key => path.match(new RegExp('^' + key)))
path404 = (key && notFoundPage[key]) || defaultPath
break
default:
break
}
return path404
}
proto._loadSideAndNav = function (path, qs, loadSidebar, cb) {
return () => {
if (!loadSidebar) {
return cb()
}
const fn = result => {
this._renderSidebar(result)
cb()
}
// Load sidebar
loadNested(path, qs, loadSidebar, fn, this, true)
}
}
proto._fetch = function (cb = noop) {
const { path, query } = this.route
const qs = stringifyQuery(query, ['id'])
const { loadNavbar, requestHeaders, loadSidebar } = this.config
// Abort last request
const file = this.router.getFile(path)
const req = request(file + qs, true, requestHeaders)
// Current page is html
this.isHTML = /\.html$/g.test(file)
// Load main content
req.then(
(text, opt) =>
this._renderMain(
text,
opt,
this._loadSideAndNav(path, qs, loadSidebar, cb)
),
_ => {
this._fetchFallbackPage(file, qs, cb) || this._fetch404(file, qs, cb)
}
)
// Load nav
loadNavbar &&
loadNested(
path,
qs,
loadNavbar,
text => this._renderNav(text),
this,
true
)
}
proto._fetchCover = function () {
const { coverpage, requestHeaders } = this.config
const query = this.route.query
const root = getParentPath(this.route.path)
if (coverpage) {
let path = null
const routePath = this.route.path
if (typeof coverpage === 'string') {
if (routePath === '/') {
path = coverpage
}
} else if (Array.isArray(coverpage)) {
path = coverpage.indexOf(routePath) > -1 && '_coverpage'
} else {
const cover = coverpage[routePath]
path = cover === true ? '_coverpage' : cover
}
const coverOnly = Boolean(path) && this.config.onlyCover
if (path) {
path = this.router.getFile(root + path)
this.coverIsHTML = /\.html$/g.test(path)
get(path + stringifyQuery(query, ['id']), false, requestHeaders).then(
text => this._renderCover(text, coverOnly)
)
} else {
this._renderCover(null, coverOnly)
}
return coverOnly
}
}
proto.$fetch = function (cb = noop) {
const done = () => {
callHook(this, 'doneEach')
cb()
}
const onlyCover = this._fetchCover()
if (onlyCover) {
done()
} else {
this._fetch(() => {
this.$resetEvents()
done()
})
}
}
proto._fetchFallbackPage = function (path, qs, cb = noop) {
const { requestHeaders, fallbackLanguages, loadSidebar } = this.config
if (!fallbackLanguages) {
return false
}
const local = path.split('/')[1]
if (fallbackLanguages.indexOf(local) === -1) {
return false
}
const newPath = path.replace(new RegExp(`^/${local}`), '')
const req = request(newPath + qs, true, requestHeaders)
req.then(
(text, opt) =>
this._renderMain(
text,
opt,
this._loadSideAndNav(path, qs, loadSidebar, cb)
),
() => this._fetch404(path, qs, cb)
)
return true
}
/**
* Load the 404 page
* @param {String} path URL to be loaded
* @param {*} qs TODO: define
* @param {Function} cb Callback
* @returns {Boolean} True if the requested page is not found
* @private
*/
proto._fetch404 = function (path, qs, cb = noop) {
const { loadSidebar, requestHeaders, notFoundPage } = this.config
const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb)
if (notFoundPage) {
const path404 = get404Path(path, this.config)
request(this.router.getFile(path404), true, requestHeaders).then(
(text, opt) => this._renderMain(text, opt, fnLoadSideAndNav),
() => this._renderMain(null, {}, fnLoadSideAndNav)
)
return true
}
this._renderMain(null, {}, fnLoadSideAndNav)
return false
}
}
export function initFetch(vm) {
const { loadSidebar } = vm.config
// Server-Side Rendering
if (vm.rendered) {
const activeEl = getAndActive(vm.router, '.sidebar-nav', true, true)
if (loadSidebar && activeEl) {
activeEl.parentNode.innerHTML += window.__SUB_SIDEBAR__
}
vm._bindEventOnRendered(activeEl)
vm.$resetEvents()
callHook(vm, 'doneEach')
callHook(vm, 'ready')
} else {
vm.$fetch(_ => callHook(vm, 'ready'))
}
}