${content.slice(5).trim()}
` + return `${content.slice(5).trim()}
`; } export function theme(color) { - return `` + return ``; } diff --git a/src/core/router/history/abstract.js b/src/core/router/history/abstract.js index 2c0bd951d..02881f165 100644 --- a/src/core/router/history/abstract.js +++ b/src/core/router/history/abstract.js @@ -1,25 +1,25 @@ -import {History} from './base' -import {parseQuery} from '../util' +import { parseQuery } from '../util'; +import { History } from './base'; export class AbstractHistory extends History { constructor(config) { - super(config) - this.mode = 'abstract' + super(config); + this.mode = 'abstract'; } parse(path) { - let query = '' + let query = ''; - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } return { path, file: this.getFile(path), - query: parseQuery(query) - } + query: parseQuery(query), + }; } } diff --git a/src/core/router/history/base.js b/src/core/router/history/base.js index 4c570df1c..68c98b7f5 100644 --- a/src/core/router/history/base.js +++ b/src/core/router/history/base.js @@ -4,57 +4,59 @@ import { stringifyQuery, cleanPath, replaceSlug, - resolvePath -} from '../util' -import {noop, merge} from '../../util/core' + resolvePath, +} from '../util'; +import { noop, merge } from '../../util/core'; -const cached = {} +const cached = {}; function getAlias(path, alias, last) { const match = Object.keys(alias).filter(key => { - const re = cached[key] || (cached[key] = new RegExp(`^${key}$`)) - return re.test(path) && path !== last - })[0] + const re = cached[key] || (cached[key] = new RegExp(`^${key}$`)); + return re.test(path) && path !== last; + })[0]; - return match ? - getAlias(path.replace(cached[match], alias[match]), alias, path) : - path + return match + ? getAlias(path.replace(cached[match], alias[match]), alias, path) + : path; } function getFileName(path, ext) { - return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) ? - path : - /\/$/g.test(path) ? `${path}README${ext}` : `${path}${ext}` + return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) + ? path + : /\/$/g.test(path) + ? `${path}README${ext}` + : `${path}${ext}`; } export class History { constructor(config) { - this.config = config + this.config = config; } getBasePath() { - return this.config.basePath + return this.config.basePath; } getFile(path = this.getCurrentPath(), isRelative) { - const {config} = this - const base = this.getBasePath() - const ext = typeof config.ext === 'string' ? config.ext : '.md' + const { config } = this; + const base = this.getBasePath(); + const ext = typeof config.ext === 'string' ? config.ext : '.md'; - path = config.alias ? getAlias(path, config.alias) : path - path = getFileName(path, ext) - path = path === `/README${ext}` ? config.homepage || path : path - path = isAbsolutePath(path) ? path : getPath(base, path) + path = config.alias ? getAlias(path, config.alias) : path; + path = getFileName(path, ext); + path = path === `/README${ext}` ? config.homepage || path : path; + path = isAbsolutePath(path) ? path : getPath(base, path); if (isRelative) { - path = path.replace(new RegExp(`^${base}`), '') + path = path.replace(new RegExp(`^${base}`), ''); } - return path + return path; } onchange(cb = noop) { - cb() + cb(); } getCurrentPath() {} @@ -64,24 +66,28 @@ export class History { parse() {} toURL(path, params, currentRoute) { - const local = currentRoute && path[0] === '#' - const route = this.parse(replaceSlug(path)) + const local = currentRoute && path[0] === '#'; + const route = this.parse(replaceSlug(path)); - route.query = merge({}, route.query, params) - path = route.path + stringifyQuery(route.query) - path = path.replace(/\.md(\?)|\.md$/, '$1') + route.query = merge({}, route.query, params); + path = route.path + stringifyQuery(route.query); + path = path.replace(/\.md(\?)|\.md$/, '$1'); if (local) { - const idIndex = currentRoute.indexOf('?') + const idIndex = currentRoute.indexOf('?'); path = - (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path + (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + + path; } if (this.config.relativePath && path.indexOf('/') !== 0) { - const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1) - return cleanPath(resolvePath(currentDir + path)) + const currentDir = currentRoute.substring( + 0, + currentRoute.lastIndexOf('/') + 1 + ); + return cleanPath(resolvePath(currentDir + path)); } - return cleanPath('/' + path) + return cleanPath('/' + path); } } diff --git a/src/core/router/history/hash.js b/src/core/router/history/hash.js index 4e1b1a361..1e099eacf 100644 --- a/src/core/router/history/hash.js +++ b/src/core/router/history/hash.js @@ -1,48 +1,48 @@ -import { History } from './base' -import { noop } from '../../util/core' -import { on } from '../../util/dom' -import { parseQuery, cleanPath, replaceSlug } from '../util' +import { noop } from '../../util/core'; +import { on } from '../../util/dom'; +import { parseQuery, cleanPath, replaceSlug } from '../util'; +import { History } from './base'; function replaceHash(path) { - const i = location.href.indexOf('#') - location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path) + const i = location.href.indexOf('#'); + location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path); } export class HashHistory extends History { constructor(config) { - super(config) - this.mode = 'hash' + super(config); + this.mode = 'hash'; } getBasePath() { - const path = window.location.pathname || '' - const base = this.config.basePath + const path = window.location.pathname || ''; + const base = this.config.basePath; - return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base) + return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base); } getCurrentPath() { // We can't use location.hash here because it's not // consistent across browsers - Firefox will pre-decode it! - const href = location.href - const index = href.indexOf('#') - return index === -1 ? '' : href.slice(index + 1) + const href = location.href; + const index = href.indexOf('#'); + return index === -1 ? '' : href.slice(index + 1); } onchange(cb = noop) { - on('hashchange', cb) + on('hashchange', cb); } normalize() { - let path = this.getCurrentPath() + let path = this.getCurrentPath(); - path = replaceSlug(path) + path = replaceSlug(path); if (path.charAt(0) === '/') { - return replaceHash(path) + return replaceHash(path); } - replaceHash('/' + path) + replaceHash('/' + path); } /** @@ -51,27 +51,27 @@ export class HashHistory extends History { * @return {object} { path, query } */ parse(path = location.href) { - let query = '' + let query = ''; - const hashIndex = path.indexOf('#') + const hashIndex = path.indexOf('#'); if (hashIndex >= 0) { - path = path.slice(hashIndex + 1) + path = path.slice(hashIndex + 1); } - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } return { path, file: this.getFile(path, true), - query: parseQuery(query) - } + query: parseQuery(query), + }; } toURL(path, params, currentRoute) { - return '#' + super.toURL(path, params, currentRoute) + return '#' + super.toURL(path, params, currentRoute); } } diff --git a/src/core/router/history/html5.js b/src/core/router/history/html5.js index a3bda1391..4ae3b8d83 100644 --- a/src/core/router/history/html5.js +++ b/src/core/router/history/html5.js @@ -1,38 +1,38 @@ -import { History } from './base' -import { noop } from '../../util/core' -import { on } from '../../util/dom' -import { parseQuery, getPath } from '../util' +import { noop } from '../../util/core'; +import { on } from '../../util/dom'; +import { parseQuery, getPath } from '../util'; +import { History } from './base'; export class HTML5History extends History { constructor(config) { - super(config) - this.mode = 'history' + super(config); + this.mode = 'history'; } getCurrentPath() { - const base = this.getBasePath() - let path = window.location.pathname + const base = this.getBasePath(); + let path = window.location.pathname; if (base && path.indexOf(base) === 0) { - path = path.slice(base.length) + path = path.slice(base.length); } - return (path || '/') + window.location.search + window.location.hash + return (path || '/') + window.location.search + window.location.hash; } onchange(cb = noop) { on('click', e => { - const el = e.target.tagName === 'A' ? e.target : e.target.parentNode + const el = e.target.tagName === 'A' ? e.target : e.target.parentNode; if (el.tagName === 'A' && !/_blank/.test(el.target)) { - e.preventDefault() - const url = el.href - window.history.pushState({ key: url }, '', url) - cb() + e.preventDefault(); + const url = el.href; + window.history.pushState({ key: url }, '', url); + cb(); } - }) + }); - on('popstate', cb) + on('popstate', cb); } /** @@ -41,25 +41,25 @@ export class HTML5History extends History { * @return {object} { path, query } */ parse(path = location.href) { - let query = '' + let query = ''; - const queryIndex = path.indexOf('?') + const queryIndex = path.indexOf('?'); if (queryIndex >= 0) { - query = path.slice(queryIndex + 1) - path = path.slice(0, queryIndex) + query = path.slice(queryIndex + 1); + path = path.slice(0, queryIndex); } - const base = getPath(location.origin) - const baseIndex = path.indexOf(base) + const base = getPath(location.origin); + const baseIndex = path.indexOf(base); if (baseIndex > -1) { - path = path.slice(baseIndex + base.length) + path = path.slice(baseIndex + base.length); } return { path, file: this.getFile(path), - query: parseQuery(query) - } + query: parseQuery(query), + }; } } diff --git a/src/core/router/index.js b/src/core/router/index.js index 943fe6c3e..6967b20b8 100644 --- a/src/core/router/index.js +++ b/src/core/router/index.js @@ -1,45 +1,46 @@ -import {HashHistory} from './history/hash' -import {HTML5History} from './history/html5' -import {supportsPushState} from '../util/env' -import * as dom from '../util/dom' +import { supportsPushState } from '../util/env'; +import * as dom from '../util/dom'; +import { HashHistory } from './history/hash'; +import { HTML5History } from './history/html5'; export function routerMixin(proto) { - proto.route = {} + proto.route = {}; } -let lastRoute = {} +let lastRoute = {}; function updateRender(vm) { - vm.router.normalize() - vm.route = vm.router.parse() - dom.body.setAttribute('data-page', vm.route.file) + vm.router.normalize(); + vm.route = vm.router.parse(); + dom.body.setAttribute('data-page', vm.route.file); } export function initRouter(vm) { - const config = vm.config - const mode = config.routerMode || 'hash' - let router + const config = vm.config; + const mode = config.routerMode || 'hash'; + let router; if (mode === 'history' && supportsPushState) { - router = new HTML5History(config) + router = new HTML5History(config); } else { - router = new HashHistory(config) + router = new HashHistory(config); } - vm.router = router - updateRender(vm) - lastRoute = vm.route + vm.router = router; + updateRender(vm); + lastRoute = vm.route; + // eslint-disable-next-line no-unused-vars router.onchange(_ => { - updateRender(vm) - vm._updateRender() + updateRender(vm); + vm._updateRender(); if (lastRoute.path === vm.route.path) { - vm.$resetEvents() - return + vm.$resetEvents(); + return; } - vm.$fetch() - lastRoute = vm.route - }) + vm.$fetch(); + lastRoute = vm.route; + }); } diff --git a/src/core/router/util.js b/src/core/router/util.js index 8b3ce7b4a..ba2eed8a1 100644 --- a/src/core/router/util.js +++ b/src/core/router/util.js @@ -1,81 +1,81 @@ -import { cached } from '../util/core' +import { cached } from '../util/core'; -const decode = decodeURIComponent -const encode = encodeURIComponent +const decode = decodeURIComponent; +const encode = encodeURIComponent; export function parseQuery(query) { - const res = {} + const res = {}; - query = query.trim().replace(/^(\?|#|&)/, '') + query = query.trim().replace(/^(\?|#|&)/, ''); if (!query) { - return res + return res; } // Simple parse - query.split('&').forEach(function (param) { - const parts = param.replace(/\+/g, ' ').split('=') + query.split('&').forEach(function(param) { + const parts = param.replace(/\+/g, ' ').split('='); - res[parts[0]] = parts[1] && decode(parts[1]) - }) + res[parts[0]] = parts[1] && decode(parts[1]); + }); - return res + return res; } export function stringifyQuery(obj, ignores = []) { - const qs = [] + const qs = []; for (const key in obj) { if (ignores.indexOf(key) > -1) { - continue + continue; } qs.push( - obj[key] ? - `${encode(key)}=${encode(obj[key])}`.toLowerCase() : - encode(key) - ) + obj[key] + ? `${encode(key)}=${encode(obj[key])}`.toLowerCase() + : encode(key) + ); } - return qs.length ? `?${qs.join('&')}` : '' + return qs.length ? `?${qs.join('&')}` : ''; } export const isAbsolutePath = cached(path => { - return /(:|(\/{2}))/g.test(path) -}) + return /(:|(\/{2}))/g.test(path); +}); export const getParentPath = cached(path => { if (/\/$/g.test(path)) { - return path + return path; } - const matchingParts = path.match(/(\S*\/)[^/]+$/) - return matchingParts ? matchingParts[1] : '' -}) + const matchingParts = path.match(/(\S*\/)[^/]+$/); + return matchingParts ? matchingParts[1] : ''; +}); export const cleanPath = cached(path => { - return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/') -}) + return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/'); +}); export const resolvePath = cached(path => { - const segments = path.replace(/^\//, '').split('/') - let resolved = [] + const segments = path.replace(/^\//, '').split('/'); + let resolved = []; for (let i = 0, len = segments.length; i < len; i++) { - const segment = segments[i] + const segment = segments[i]; if (segment === '..') { - resolved.pop() + resolved.pop(); } else if (segment !== '.') { - resolved.push(segment) + resolved.push(segment); } } - return '/' + resolved.join('/') -}) + return '/' + resolved.join('/'); +}); export function getPath(...args) { - return cleanPath(args.join('/')) + return cleanPath(args.join('/')); } export const replaceSlug = cached(path => { - return path.replace('#', '?id=') -}) + return path.replace('#', '?id='); +}); diff --git a/src/core/util/core.js b/src/core/util/core.js index 2d4f20c9b..9d2638412 100644 --- a/src/core/util/core.js +++ b/src/core/util/core.js @@ -5,22 +5,22 @@ */ export function cached(fn) { - const cache = Object.create(null) - return function (str) { - const key = isPrimitive(str) ? str : JSON.stringify(str) - const hit = cache[key] - return hit || (cache[key] = fn(str)) - } + const cache = Object.create(null); + return function(str) { + const key = isPrimitive(str) ? str : JSON.stringify(str); + const hit = cache[key]; + return hit || (cache[key] = fn(str)); + }; } /** * Hyphenate a camelCase string. */ export const hyphenate = cached(str => { - return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase()) -}) + return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase()); +}); -export const hasOwn = Object.prototype.hasOwnProperty +export const hasOwn = Object.prototype.hasOwnProperty; /** * Simple Object.assign polyfill @@ -29,19 +29,19 @@ export const hasOwn = Object.prototype.hasOwnProperty */ export const merge = Object.assign || - function (to) { + function(to) { for (let i = 1; i < arguments.length; i++) { - const from = Object(arguments[i]) + const from = Object(arguments[i]); for (const key in from) { if (hasOwn.call(from, key)) { - to[key] = from[key] + to[key] = from[key]; } } } - return to - } + return to; + }; /** * Check if value is primitive @@ -49,14 +49,14 @@ export const merge = * @returns {Boolean} Result of the check */ export function isPrimitive(value) { - return typeof value === 'string' || typeof value === 'number' + return typeof value === 'string' || typeof value === 'number'; } /** * Performs no operation. * @void */ -export function noop() { } +export function noop() {} /** * Check if value is function @@ -64,6 +64,5 @@ export function noop() { } * @returns {Boolean} True if the passed-in value is a function */ export function isFn(obj) { - return typeof obj === 'function' + return typeof obj === 'function'; } - diff --git a/src/core/util/dom.js b/src/core/util/dom.js index 3d529bba5..b17628636 100644 --- a/src/core/util/dom.js +++ b/src/core/util/dom.js @@ -1,7 +1,7 @@ -import { isFn } from '../util/core' -import { inBrowser } from './env' +import { isFn } from '../util/core'; +import { inBrowser } from './env'; -const cacheNode = {} +const cacheNode = {}; /** * Get Node @@ -12,20 +12,20 @@ const cacheNode = {} export function getNode(el, noCache = false) { if (typeof el === 'string') { if (typeof window.Vue !== 'undefined') { - return find(el) + return find(el); } - el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el)) + el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el)); } - return el + return el; } -export const $ = inBrowser && document +export const $ = inBrowser && document; -export const body = inBrowser && $.body +export const body = inBrowser && $.body; -export const head = inBrowser && $.head +export const head = inBrowser && $.head; /** * Find elements @@ -37,7 +37,7 @@ export const head = inBrowser && $.head * find(nav, 'a') => nav.querySelector('a') */ export function find(el, node) { - return node ? el.querySelector(node) : $.querySelector(el) + return node ? el.querySelector(node) : $.querySelector(el); } /** @@ -52,36 +52,36 @@ export function find(el, node) { export function findAll(el, node) { return [].slice.call( node ? el.querySelectorAll(node) : $.querySelectorAll(el) - ) + ); } export function create(node, tpl) { - node = $.createElement(node) + node = $.createElement(node); if (tpl) { - node.innerHTML = tpl + node.innerHTML = tpl; } - return node + return node; } export function appendTo(target, el) { - return target.appendChild(el) + return target.appendChild(el); } export function before(target, el) { - return target.insertBefore(el, target.children[0]) + return target.insertBefore(el, target.children[0]); } export function on(el, type, handler) { - isFn(type) ? - window.addEventListener(el, type) : - el.addEventListener(type, handler) + isFn(type) + ? window.addEventListener(el, type) + : el.addEventListener(type, handler); } export function off(el, type, handler) { - isFn(type) ? - window.removeEventListener(el, type) : - el.removeEventListener(type, handler) + isFn(type) + ? window.removeEventListener(el, type) + : el.removeEventListener(type, handler); } /** @@ -95,9 +95,9 @@ export function off(el, type, handler) { * toggleClass(el, 'add', 'active') => el.classList.add('active') */ export function toggleClass(el, type, val) { - el && el.classList[val ? type : 'toggle'](val || type) + el && el.classList[val ? type : 'toggle'](val || type); } export function style(content) { - appendTo(head, create('style', content)) + appendTo(head, create('style', content)); } diff --git a/src/core/util/env.js b/src/core/util/env.js index cd5163558..015179c58 100644 --- a/src/core/util/env.js +++ b/src/core/util/env.js @@ -1,13 +1,13 @@ -export const inBrowser = !process.env.SSR +export const inBrowser = !process.env.SSR; -export const isMobile = inBrowser && document.body.clientWidth <= 600 +export const isMobile = inBrowser && document.body.clientWidth <= 600; /** * @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js */ export const supportsPushState = inBrowser && - (function () { + (function() { // Borrowed wholesale from https://github.com/defunkt/jquery-pjax return ( window.history && @@ -17,5 +17,5 @@ export const supportsPushState = !navigator.userAgent.match( /((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/ ) - ) - })() + ); + })(); diff --git a/src/core/util/index.js b/src/core/util/index.js index eba6598f5..444ea9d47 100644 --- a/src/core/util/index.js +++ b/src/core/util/index.js @@ -1,3 +1,3 @@ -export * from './core' -export * from './env' -export * from '../router/util' +export * from './core'; +export * from './env'; +export * from '../router/util'; diff --git a/src/core/util/polyfill/css-vars.js b/src/core/util/polyfill/css-vars.js index fb3a80a2b..34e201f28 100644 --- a/src/core/util/polyfill/css-vars.js +++ b/src/core/util/polyfill/css-vars.js @@ -1,36 +1,36 @@ -import * as dom from '../dom' -import {get} from '../../fetch/ajax' +import * as dom from '../dom'; +import { get } from '../../fetch/ajax'; function replaceVar(block, color) { block.innerHTML = block.innerHTML.replace( /var\(\s*--theme-color.*?\)/g, color - ) + ); } -export default function (color) { +export default function(color) { // Variable support if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) { - return + return; } const styleBlocks = dom.findAll('style:not(.inserted),link'); [].forEach.call(styleBlocks, block => { if (block.nodeName === 'STYLE') { - replaceVar(block, color) + replaceVar(block, color); } else if (block.nodeName === 'LINK') { - const href = block.getAttribute('href') + const href = block.getAttribute('href'); if (!/\.css$/.test(href)) { - return + return; } get(href).then(res => { - const style = dom.create('style', res) + const style = dom.create('style', res); - dom.head.appendChild(style) - replaceVar(style, color) - }) + dom.head.appendChild(style); + replaceVar(style, color); + }); } - }) + }); } diff --git a/src/plugins/disqus.js b/src/plugins/disqus.js index dba7aef82..4355692ec 100644 --- a/src/plugins/disqus.js +++ b/src/plugins/disqus.js @@ -1,51 +1,52 @@ -const fixedPath = location.href.replace('/-/', '/#/') +/* eslint-disable no-unused-vars */ +const fixedPath = location.href.replace('/-/', '/#/'); if (fixedPath !== location.href) { - location.href = fixedPath + location.href = fixedPath; } function install(hook, vm) { - const dom = Docsify.dom - const disqus = vm.config.disqus + const dom = Docsify.dom; + const disqus = vm.config.disqus; if (!disqus) { - throw Error('$docsify.disqus is required') + throw Error('$docsify.disqus is required'); } hook.init(_ => { - const script = dom.create('script') + const script = dom.create('script'); - script.async = true - script.src = `https://${disqus}.disqus.com/embed.js` - script.setAttribute('data-timestamp', Number(new Date())) - dom.appendTo(dom.body, script) - }) + script.async = true; + script.src = `https://${disqus}.disqus.com/embed.js`; + script.setAttribute('data-timestamp', Number(new Date())); + dom.appendTo(dom.body, script); + }); hook.mounted(_ => { - const div = dom.create('div') - div.id = 'disqus_thread' - const main = dom.getNode('#main') - div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;` - dom.appendTo(dom.find('.content'), div) + const div = dom.create('div'); + div.id = 'disqus_thread'; + const main = dom.getNode('#main'); + div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`; + dom.appendTo(dom.find('.content'), div); // eslint-disable-next-line window.disqus_config = function() { - this.page.url = location.origin + '/-' + vm.route.path - this.page.identifier = vm.route.path - this.page.title = document.title - } - }) + this.page.url = location.origin + '/-' + vm.route.path; + this.page.identifier = vm.route.path; + this.page.title = document.title; + }; + }); hook.doneEach(_ => { if (typeof window.DISQUS !== 'undefined') { window.DISQUS.reset({ reload: true, - config: function () { - this.page.url = location.origin + '/-' + vm.route.path - this.page.identifier = vm.route.path - this.page.title = document.title - } - }) + config: function() { + this.page.url = location.origin + '/-' + vm.route.path; + this.page.identifier = vm.route.path; + this.page.title = document.title; + }, + }); } - }) + }); } -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/emoji.js b/src/plugins/emoji.js index e65e42c4b..2898c3d04 100644 --- a/src/plugins/emoji.js +++ b/src/plugins/emoji.js @@ -1508,17 +1508,17 @@ const AllGithubEmoji = [ 'zero', 'zimbabwe', 'zipper_mouth_face', - 'zzz' -] + 'zzz', +]; // Emoji from All-Github-Emoji-Icons // https://github.com/scotch-io/All-Github-Emoji-Icons -window.emojify = function (match, $1) { - return AllGithubEmoji.indexOf($1) === -1 ? - match : - '${NO_DATA_TEXT}
` + $panel.classList.add('show'); + $clearBtn.classList.add('show'); + $panel.innerHTML = html || `${NO_DATA_TEXT}
`; if (options.hideOtherSidebarContent) { - $sidebarNav.classList.add('hide') - $appName.classList.add('hide') + $sidebarNav.classList.add('hide'); + $appName.classList.add('hide'); } } function bindEvents() { - const $search = Docsify.dom.find('div.search') - const $input = Docsify.dom.find($search, 'input') - const $inputWrap = Docsify.dom.find($search, '.input-wrap') + const $search = Docsify.dom.find('div.search'); + const $input = Docsify.dom.find($search, 'input'); + const $inputWrap = Docsify.dom.find($search, '.input-wrap'); - let timeId + let timeId; // Prevent to Fold sidebar Docsify.dom.on( $search, 'click', e => e.target.tagName !== 'A' && e.stopPropagation() - ) + ); Docsify.dom.on($input, 'input', e => { - clearTimeout(timeId) - timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100) - }) + clearTimeout(timeId); + timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100); + }); Docsify.dom.on($inputWrap, 'click', e => { // Click input outside if (e.target.tagName !== 'INPUT') { - $input.value = '' - doSearch() + $input.value = ''; + doSearch(); } - }) + }); } function updatePlaceholder(text, path) { - const $input = Docsify.dom.getNode('.search input[type="search"]') + const $input = Docsify.dom.getNode('.search input[type="search"]'); if (!$input) { - return + return; } if (typeof text === 'string') { - $input.placeholder = text + $input.placeholder = text; } else { - const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0] - $input.placeholder = text[match] + const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; + $input.placeholder = text[match]; } } function updateNoData(text, path) { if (typeof text === 'string') { - NO_DATA_TEXT = text + NO_DATA_TEXT = text; } else { - const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0] - NO_DATA_TEXT = text[match] + const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]; + NO_DATA_TEXT = text[match]; } } function updateOptions(opts) { - options = opts + options = opts; } export function init(opts, vm) { - const keywords = vm.router.parse().query.s + const keywords = vm.router.parse().query.s; - updateOptions(opts) - style() - tpl(keywords) - bindEvents() - keywords && setTimeout(_ => doSearch(keywords), 500) + updateOptions(opts); + style(); + tpl(keywords); + bindEvents(); + keywords && setTimeout(_ => doSearch(keywords), 500); } export function update(opts, vm) { - updateOptions(opts) - updatePlaceholder(opts.placeholder, vm.route.path) - updateNoData(opts.noData, vm.route.path) + updateOptions(opts); + updatePlaceholder(opts.placeholder, vm.route.path); + updateNoData(opts.noData, vm.route.path); } diff --git a/src/plugins/search/index.js b/src/plugins/search/index.js index bbd3af6f0..3bfd3b6b5 100644 --- a/src/plugins/search/index.js +++ b/src/plugins/search/index.js @@ -1,5 +1,6 @@ -import {init as initComponet, update as updateComponent} from './component' -import {init as initSearch} from './search' +/* eslint-disable no-unused-vars */ +import { init as initComponet, update as updateComponent } from './component'; +import { init as initSearch } from './search'; const CONFIG = { placeholder: 'Type to search', @@ -8,35 +9,36 @@ const CONFIG = { depth: 2, maxAge: 86400000, // 1 day hideOtherSidebarContent: false, - namespace: undefined -} + namespace: undefined, +}; -const install = function (hook, vm) { - const {util} = Docsify - const opts = vm.config.search || CONFIG +const install = function(hook, vm) { + const { util } = Docsify; + const opts = vm.config.search || CONFIG; if (Array.isArray(opts)) { - CONFIG.paths = opts + CONFIG.paths = opts; } else if (typeof opts === 'object') { - CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto' - CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge - CONFIG.placeholder = opts.placeholder || CONFIG.placeholder - CONFIG.noData = opts.noData || CONFIG.noData - CONFIG.depth = opts.depth || CONFIG.depth - CONFIG.hideOtherSidebarContent = opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent - CONFIG.namespace = opts.namespace || CONFIG.namespace + CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto'; + CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge; + CONFIG.placeholder = opts.placeholder || CONFIG.placeholder; + CONFIG.noData = opts.noData || CONFIG.noData; + CONFIG.depth = opts.depth || CONFIG.depth; + CONFIG.hideOtherSidebarContent = + opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent; + CONFIG.namespace = opts.namespace || CONFIG.namespace; } - const isAuto = CONFIG.paths === 'auto' + const isAuto = CONFIG.paths === 'auto'; hook.mounted(_ => { - initComponet(CONFIG, vm) - !isAuto && initSearch(CONFIG, vm) - }) + initComponet(CONFIG, vm); + !isAuto && initSearch(CONFIG, vm); + }); hook.doneEach(_ => { - updateComponent(CONFIG, vm) - isAuto && initSearch(CONFIG, vm) - }) -} + updateComponent(CONFIG, vm); + isAuto && initSearch(CONFIG, vm); + }); +}; -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js index fe124d7d0..29d74b79e 100644 --- a/src/plugins/search/search.js +++ b/src/plugins/search/search.js @@ -1,16 +1,21 @@ -let INDEXS = {} +/* eslint-disable no-unused-vars */ +let INDEXS = {}; const LOCAL_STORAGE = { EXPIRE_KEY: 'docsify.search.expires', - INDEX_KEY: 'docsify.search.index' -} + INDEX_KEY: 'docsify.search.index', +}; function resolveExpireKey(namespace) { - return namespace ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` : LOCAL_STORAGE.EXPIRE_KEY + return namespace + ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` + : LOCAL_STORAGE.EXPIRE_KEY; } function resolveIndexKey(namespace) { - return namespace ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` : LOCAL_STORAGE.INDEX_KEY + return namespace + ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` + : LOCAL_STORAGE.INDEX_KEY; } function escapeHtml(string) { @@ -19,72 +24,78 @@ function escapeHtml(string) { '<': '<', '>': '>', '"': '"', - '\'': ''', - '/': '/' - } + "'": ''', + '/': '/', + }; - return String(string).replace(/[&<>"'/]/g, s => entityMap[s]) + return String(string).replace(/[&<>"'/]/g, s => entityMap[s]); } function getAllPaths(router) { - const paths = [] - - Docsify.dom.findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])').forEach(node => { - const href = node.href - const originHref = node.getAttribute('href') - const path = router.parse(href).path - - if ( - path && - paths.indexOf(path) === -1 && - !Docsify.util.isAbsolutePath(originHref) - ) { - paths.push(path) - } - }) + const paths = []; + + Docsify.dom + .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])') + .forEach(node => { + const href = node.href; + const originHref = node.getAttribute('href'); + const path = router.parse(href).path; + + if ( + path && + paths.indexOf(path) === -1 && + !Docsify.util.isAbsolutePath(originHref) + ) { + paths.push(path); + } + }); - return paths + return paths; } function saveData(maxAge, expireKey, indexKey) { - localStorage.setItem(expireKey, Date.now() + maxAge) - localStorage.setItem(indexKey, JSON.stringify(INDEXS)) + localStorage.setItem(expireKey, Date.now() + maxAge); + localStorage.setItem(indexKey, JSON.stringify(INDEXS)); } export function genIndex(path, content = '', router, depth) { - const tokens = window.marked.lexer(content) - const slugify = window.Docsify.slugify - const index = {} - let slug + const tokens = window.marked.lexer(content); + const slugify = window.Docsify.slugify; + const index = {}; + let slug; tokens.forEach(token => { if (token.type === 'heading' && token.depth <= depth) { - slug = router.toURL(path, { id: slugify(token.text) }) - index[slug] = { slug, title: token.text, body: '' } + slug = router.toURL(path, { id: slugify(token.text) }); + index[slug] = { slug, title: token.text, body: '' }; } else { if (!slug) { - return + return; } if (!index[slug]) { - index[slug] = { slug, title: '', body: '' } + index[slug] = { slug, title: '', body: '' }; } else if (index[slug].body) { - index[slug].body += '\n' + (token.text || '') + index[slug].body += '\n' + (token.text || ''); } else { if (!token.text) { if (token.type === 'table') { - token.text = token.cells.map(function (rows) { - return rows.join(' | ') - }).join(' |\n ') + token.text = token.cells + .map(function(rows) { + return rows.join(' | '); + }) + .join(' |\n '); } } - index[slug].body = (index[slug].body ? index[slug].body + token.text : token.text) + index[slug].body = index[slug].body + ? index[slug].body + token.text + : token.text; } } - }) - slugify.clear() - return index + }); + slugify.clear(); + return index; } /** @@ -92,25 +103,25 @@ export function genIndex(path, content = '', router, depth) { * @returns {Array} Array of results */ export function search(query) { - const matchingResults = [] - let data = [] + const matchingResults = []; + let data = []; Object.keys(INDEXS).forEach(key => { - data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page])) - }) + data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page])); + }); - query = query.trim() - let keywords = query.split(/[\s\-,\\/]+/) + query = query.trim(); + let keywords = query.split(/[\s\-,\\/]+/); if (keywords.length !== 1) { - keywords = [].concat(query, keywords) + keywords = [].concat(query, keywords); } for (let i = 0; i < data.length; i++) { - const post = data[i] - let matchesScore = 0 - let resultStr = '' - const postTitle = post.title && post.title.trim() - const postContent = post.body && post.body.trim() - const postUrl = post.slug || '' + const post = data[i]; + let matchesScore = 0; + let resultStr = ''; + const postTitle = post.title && post.title.trim(); + const postContent = post.body && post.body.trim(); + const postUrl = post.slug || ''; if (postTitle) { keywords.forEach(keyword => { @@ -118,27 +129,27 @@ export function search(query) { const regEx = new RegExp( keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'), 'gi' - ) - let indexTitle = -1 - let indexContent = -1 + ); + let indexTitle = -1; + let indexContent = -1; - indexTitle = postTitle ? postTitle.search(regEx) : -1 - indexContent = postContent ? postContent.search(regEx) : -1 + indexTitle = postTitle ? postTitle.search(regEx) : -1; + indexContent = postContent ? postContent.search(regEx) : -1; if (indexTitle >= 0 || indexContent >= 0) { - matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0 + matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0; if (indexContent < 0) { - indexContent = 0 + indexContent = 0; } - let start = 0 - let end = 0 + let start = 0; + let end = 0; - start = indexContent < 11 ? 0 : indexContent - 10 - end = start === 0 ? 70 : indexContent + keyword.length + 60 + start = indexContent < 11 ? 0 : indexContent - 10; + end = start === 0 ? 70 : indexContent + keyword.length + 60; if (postContent && end > postContent.length) { - end = postContent.length + end = postContent.length; } const matchContent = @@ -146,58 +157,58 @@ export function search(query) { escapeHtml(postContent) .substring(start, end) .replace(regEx, `${keyword}`) + - '...' + '...'; - resultStr += matchContent + resultStr += matchContent; } - }) + }); if (matchesScore > 0) { const matchingPost = { title: escapeHtml(postTitle), content: postContent ? resultStr : '', url: postUrl, - score: matchesScore - } + score: matchesScore, + }; - matchingResults.push(matchingPost) + matchingResults.push(matchingPost); } } } - return matchingResults.sort((r1, r2) => r2.score - r1.score) + return matchingResults.sort((r1, r2) => r2.score - r1.score); } export function init(config, vm) { - const isAuto = config.paths === 'auto' + const isAuto = config.paths === 'auto'; - const expireKey = resolveExpireKey(config.namespace) - const indexKey = resolveIndexKey(config.namespace) + const expireKey = resolveExpireKey(config.namespace); + const indexKey = resolveIndexKey(config.namespace); - const isExpired = localStorage.getItem(expireKey) < Date.now() + const isExpired = localStorage.getItem(expireKey) < Date.now(); - INDEXS = JSON.parse(localStorage.getItem(indexKey)) + INDEXS = JSON.parse(localStorage.getItem(indexKey)); if (isExpired) { - INDEXS = {} + INDEXS = {}; } else if (!isAuto) { - return + return; } - const paths = isAuto ? getAllPaths(vm.router) : config.paths - const len = paths.length - let count = 0 + const paths = isAuto ? getAllPaths(vm.router) : config.paths; + const len = paths.length; + let count = 0; paths.forEach(path => { if (INDEXS[path]) { - return count++ + return count++; } - Docsify - .get(vm.router.getFile(path), false, vm.config.requestHeaders) - .then(result => { - INDEXS[path] = genIndex(path, result, vm.router, config.depth) - len === ++count && saveData(config.maxAge, expireKey, indexKey) - }) - }) + Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then( + result => { + INDEXS[path] = genIndex(path, result, vm.router, config.depth); + len === ++count && saveData(config.maxAge, expireKey, indexKey); + } + ); + }); } diff --git a/src/plugins/zoom-image.js b/src/plugins/zoom-image.js index faf92e1dd..f227e9fee 100644 --- a/src/plugins/zoom-image.js +++ b/src/plugins/zoom-image.js @@ -1,21 +1,30 @@ -import mediumZoom from 'medium-zoom' +/* eslint-disable no-unused-vars */ +import mediumZoom from 'medium-zoom'; -const matchesSelector = Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector +const matchesSelector = + Element.prototype.matches || + Element.prototype.webkitMatchesSelector || + Element.prototype.msMatchesSelector; function install(hook) { - let zoom + let zoom; hook.doneEach(_ => { - let elms = Array.apply(null, document.querySelectorAll('.markdown-section img:not(.emoji):not([data-no-zoom])')) + let elms = Array.apply( + null, + document.querySelectorAll( + '.markdown-section img:not(.emoji):not([data-no-zoom])' + ) + ); - elms = elms.filter(elm => matchesSelector.call(elm, 'a img') === false) + elms = elms.filter(elm => matchesSelector.call(elm, 'a img') === false); if (zoom) { - zoom.detach() + zoom.detach(); } - zoom = mediumZoom(elms) - }) + zoom = mediumZoom(elms); + }); } -$docsify.plugins = [].concat(install, $docsify.plugins) +$docsify.plugins = [].concat(install, $docsify.plugins); diff --git a/test/_helper.js b/test/_helper.js index b638cd819..afd0c07fd 100644 --- a/test/_helper.js +++ b/test/_helper.js @@ -1,22 +1,29 @@ +/* eslint-disable no-global-assign */ // Load ES6 modules in Node.js on the fly -require = require('esm')(module/* , options */) /* eslint-disable-line no-global-assign */ +require = require('esm')( + module /* , options */ +); /* eslint-disable-line no-global-assign */ -const path = require('path') -const { expect } = require('chai') +const path = require('path'); +const { expect } = require('chai'); -const { JSDOM } = require('jsdom') +const { JSDOM } = require('jsdom'); function ready(callback) { - const state = document.readyState + const state = document.readyState; if (state === 'complete' || state === 'interactive') { - return setTimeout(callback, 0) + return setTimeout(callback, 0); } - document.addEventListener('DOMContentLoaded', callback) + document.addEventListener('DOMContentLoaded', callback); } -module.exports.init = function (fixture = 'default', config = {}, markup = null) { +module.exports.init = function( + fixture = 'default', + config = {}, + markup = null +) { if (markup === null || markup === undefined) { markup = ` @@ -27,64 +34,67 @@ module.exports.init = function (fixture = 'default', config = {}, markup = null) window.$docsify = ${JSON.stringify(config, null, 2)} -