UNPKG

docsify

Version:

A magical documentation generator.

224 lines (196 loc) 6.43 kB
import { stripIndent } from 'common-tags'; import { hyphenate, isPrimitive } from './util/core.js'; /** @import { Docsify } from './Docsify.js' */ /** @import { Hooks } from './init/lifecycle.js' */ const currentScript = document.currentScript; const defaultDocsifyConfig = () => ({ alias: /** @type {Record<string, string>} */ ({}), auto2top: false, autoHeader: false, basePath: '', catchPluginErrors: true, cornerExternalLinkTarget: /** @type {'_blank' | '_self' | '_parent' | '_top' | '_unfencedTop'} */ ( '_blank' ), coverpage: /** @type {boolean | string} */ (''), el: '#app', executeScript: /** @type {null | boolean} */ (null), ext: '.md', externalLinkRel: /** @type {'noopener' | string} */ ('noopener'), // TODO string union type based on spec externalLinkTarget: /** @type {'_blank' | '_self' | '_parent' | '_top' | '_unfencedTop'} */ ( '_blank' ), fallbackLanguages: /** @type {null | string[]} */ (null), fallbackDefaultLanguage: '', formatUpdated: /** @type {string | ((updatedAt: string) => string)} */ (''), pageTitleFormatter: /** @type {null | ((name: string) => string)} */ (null), /** For the frontmatter plugin. */ frontMatter: /** @type {Record<string, TODO> | null} */ (null), hideSidebar: false, homepage: 'README.md', keyBindings: /** @type {false | { [commandName: string]: { bindings: string[]; callback: Function } }} */ ({}), loadNavbar: /** @type {null | boolean | string} */ (null), loadSidebar: /** @type {null | boolean | string} */ (null), logo: false, markdown: null, maxLevel: 6, mergeNavbar: false, name: /** @type {boolean | string} */ (''), nameLink: window.location.pathname, nativeEmoji: false, noCompileLinks: /** @type {string[]} */ ([]), noEmoji: false, notFoundPage: /** @type {boolean | string | Record<string, string>} */ ( false ), onlyCover: false, plugins: /** @type {Plugin[]} */ ([]), relativePath: false, repo: /** @type {string} */ (''), requestHeaders: /** @type {Record<string, string>} */ ({}), routerMode: /** @type {'hash' | 'history'} */ 'hash', routes: /** @type {Record<string, string | RouteHandler>} */ ({}), skipLink: /** @type {false | string | Record<string, string>} */ ( 'Skip to main content' ), subMaxLevel: 0, vueComponents: /** @type {Record<string, TODO>} */ ({}), vueGlobalOptions: /** @type {Record<string, TODO>} */ ({}), vueMounts: /** @type {Record<string, TODO>} */ ({}), // Deprecations ////////////////// /** @deprecated */ get themeColor() { return this.__themeColor; }, set themeColor(value) { if (value) { this.__themeColor = value; // eslint-disable-next-line no-console console.warn( stripIndent(` $docsify.themeColor is deprecated as of v5. Use the "--theme-color" CSS property to customize your theme color. <style> :root { --theme-color: deeppink; } </style> `).trim(), ); } }, __themeColor: '', /** @deprecated */ get topMargin() { return this.__topMargin; }, set topMargin(value) { if (value) { this.__topMargin = value; // eslint-disable-next-line no-console console.warn( stripIndent(` $docsify.topMargin is deprecated as of v5. Use the "--scroll-padding-top" CSS property to specify a scroll margin when using a sticky navbar. <style> :root { --scroll-padding-top: 10px; } </style> `).trim(), ); } }, __topMargin: 0, }); /** @typedef {ReturnType<typeof defaultDocsifyConfig>} DocsifyConfig */ /** * @param {import('./Docsify.js').Docsify} vm * @param {Partial<DocsifyConfig>} config * @returns {DocsifyConfig} */ export default function (vm, config = {}) { config = Object.assign( defaultDocsifyConfig(), // Handle non-function configs no matter what (f.e. plugins assign options onto it) window.$docsify, // Also handle function config (the app can specificy a function, and plugins will assign options onto it) typeof window.$docsify === 'function' ? window.$docsify(vm) : undefined, // Finally, user config passed directly to the instance has priority. config, ); // Merge default and user-specified key bindings if (config.keyBindings !== false) { config.keyBindings = Object.assign( // Default { toggleSidebar: { bindings: ['\\'], callback(/** @type {KeyboardEvent} */ e) { const toggleElm = /** @type {HTMLElement} */ ( document.querySelector('.sidebar-toggle-button') ); if (toggleElm) { toggleElm.click(); } }, }, }, // User-specified config.keyBindings, ); } const script = currentScript || Array.from(document.getElementsByTagName('script')).filter(n => /docsify\./.test(n.src), )[0]; if (script) { for (const prop of /** @type {(keyof DocsifyConfig)[]} */ ( Object.keys(config) )) { const val = script.getAttribute('data-' + hyphenate(prop)); if (isPrimitive(val)) { // eslint-disable-next-line no-console console.warn( `DEPRECATION: data-* attributes on the docsify global script (f.e. ${ 'data-' + hyphenate(prop) }) are deprecated.`, ); // @ts-expect-error too dynamic for TS config[prop] = val === '' ? true : val; } } } 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.name === true) { config.name = ''; } return /** @type {DocsifyConfig} */ (config); } /** @typedef {any} TODO */ /** @typedef {(hooks: Hooks, vm: Docsify) => void} Plugin */ /** @typedef {( ((route: string, matched: RegExpMatchArray) => string) | ((route: string, matched: RegExpMatchArray, next: (markdown?: string) => void) => void) )} RouteHandler - Given a route, provides the markdown to render for that route. */ /** @typedef { { subMaxLevel: number, themeColor: string, topMargin: number, } } DocsifyConfigOld */