123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535 |
- (function () {
- /**
- * Converts a colon formatted string to a object with properties.
- *
- * This is process a provided string and look for any tokens in the format
- * of `:name[=value]` and then convert it to a object and return.
- * An example of this is ':include :type=code :fragment=demo' is taken and
- * then converted to:
- *
- * ```
- * {
- * include: '',
- * type: 'code',
- * fragment: 'demo'
- * }
- * ```
- *
- * @param {string} str The string to parse.
- *
- * @return {object} The original string and parsed object, { str, config }.
- */
- function getAndRemoveConfig(str) {
- if ( str === void 0 ) str = '';
- var config = {};
- if (str) {
- str = str
- .replace(/^('|")/, '')
- .replace(/('|")$/, '')
- .replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g, function (m, key, value) {
- if (key.indexOf(':') === -1) {
- config[key] = (value && value.replace(/"/g, '')) || true;
- return '';
- }
- return m;
- })
- .trim();
- }
- return { str: str, config: config };
- }
- /* eslint-disable no-unused-vars */
- var INDEXS = {};
- var LOCAL_STORAGE = {
- EXPIRE_KEY: 'docsify.search.expires',
- INDEX_KEY: 'docsify.search.index',
- };
- function resolveExpireKey(namespace) {
- 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;
- }
- function escapeHtml(string) {
- var entityMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- };
- return String(string).replace(/[&<>"']/g, function (s) { return entityMap[s]; });
- }
- function getAllPaths(router) {
- var paths = [];
- Docsify.dom
- .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])')
- .forEach(function (node) {
- var href = node.href;
- var originHref = node.getAttribute('href');
- var path = router.parse(href).path;
- if (
- path &&
- paths.indexOf(path) === -1 &&
- !Docsify.util.isAbsolutePath(originHref)
- ) {
- paths.push(path);
- }
- });
- return paths;
- }
- function getTableData(token) {
- if (!token.text && token.type === 'table' && token.cells) {
- token.cells.unshift(token.header);
- token.text = token.cells
- .map(function(rows) {
- return rows.join(' | ');
- })
- .join(' |\n ');
- }
- return token.text;
- }
- function getListData(token) {
- if (!token.text && token.type === 'list') {
- token.text = token.raw;
- }
- return token.text;
- }
- function saveData(maxAge, expireKey, indexKey) {
- localStorage.setItem(expireKey, Date.now() + maxAge);
- localStorage.setItem(indexKey, JSON.stringify(INDEXS));
- }
- function genIndex(path, content, router, depth) {
- if ( content === void 0 ) content = '';
- var tokens = window.marked.lexer(content);
- var slugify = window.Docsify.slugify;
- var index = {};
- var slug;
- var title = '';
- tokens.forEach(function(token, tokenIndex) {
- if (token.type === 'heading' && token.depth <= depth) {
- var ref = getAndRemoveConfig(token.text);
- var str = ref.str;
- var config = ref.config;
- if (config.id) {
- slug = router.toURL(path, { id: slugify(config.id) });
- } else {
- slug = router.toURL(path, { id: slugify(escapeHtml(token.text)) });
- }
- if (str) {
- title = str
- .replace(/<!-- {docsify-ignore} -->/, '')
- .replace(/{docsify-ignore}/, '')
- .replace(/<!-- {docsify-ignore-all} -->/, '')
- .replace(/{docsify-ignore-all}/, '')
- .trim();
- }
- index[slug] = { slug: slug, title: title, body: '' };
- } else {
- if (tokenIndex === 0) {
- slug = router.toURL(path);
- index[slug] = {
- slug: slug,
- title: path !== '/' ? path.slice(1) : 'Home Page',
- body: token.text || '',
- };
- }
- if (!slug) {
- return;
- }
- if (!index[slug]) {
- index[slug] = { slug: slug, title: '', body: '' };
- } else if (index[slug].body) {
- token.text = getTableData(token);
- token.text = getListData(token);
- index[slug].body += '\n' + (token.text || '');
- } else {
- token.text = getTableData(token);
- token.text = getListData(token);
- index[slug].body = index[slug].body
- ? index[slug].body + token.text
- : token.text;
- }
- }
- });
- slugify.clear();
- return index;
- }
- function ignoreDiacriticalMarks(keyword) {
- if (keyword && keyword.normalize) {
- return keyword.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
- }
- return keyword;
- }
- /**
- * @param {String} query Search query
- * @returns {Array} Array of results
- */
- function search(query) {
- var matchingResults = [];
- var data = [];
- Object.keys(INDEXS).forEach(function (key) {
- data = data.concat(Object.keys(INDEXS[key]).map(function (page) { return INDEXS[key][page]; }));
- });
- query = query.trim();
- var keywords = query.split(/[\s\-,\\/]+/);
- if (keywords.length !== 1) {
- keywords = [].concat(query, keywords);
- }
- var loop = function ( i ) {
- var post = data[i];
- var matchesScore = 0;
- var resultStr = '';
- var handlePostTitle = '';
- var handlePostContent = '';
- var postTitle = post.title && post.title.trim();
- var postContent = post.body && post.body.trim();
- var postUrl = post.slug || '';
- if (postTitle) {
- keywords.forEach(function (keyword) {
- // From https://github.com/sindresorhus/escape-string-regexp
- var regEx = new RegExp(
- escapeHtml(ignoreDiacriticalMarks(keyword)).replace(
- /[|\\{}()[\]^$+*?.]/g,
- '\\$&'
- ),
- 'gi'
- );
- var indexTitle = -1;
- var indexContent = -1;
- handlePostTitle = postTitle
- ? escapeHtml(ignoreDiacriticalMarks(postTitle))
- : postTitle;
- handlePostContent = postContent
- ? escapeHtml(ignoreDiacriticalMarks(postContent))
- : postContent;
- indexTitle = postTitle ? handlePostTitle.search(regEx) : -1;
- indexContent = postContent ? handlePostContent.search(regEx) : -1;
- if (indexTitle >= 0 || indexContent >= 0) {
- matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
- if (indexContent < 0) {
- indexContent = 0;
- }
- var start = 0;
- var end = 0;
- start = indexContent < 11 ? 0 : indexContent - 10;
- end = start === 0 ? 70 : indexContent + keyword.length + 60;
- if (postContent && end > postContent.length) {
- end = postContent.length;
- }
- var matchContent =
- '...' +
- handlePostContent
- .substring(start, end)
- .replace(
- regEx,
- function (word) { return ("<em class=\"search-keyword\">" + word + "</em>"); }
- ) +
- '...';
- resultStr += matchContent;
- }
- });
- if (matchesScore > 0) {
- var matchingPost = {
- title: handlePostTitle,
- content: postContent ? resultStr : '',
- url: postUrl,
- score: matchesScore,
- };
- matchingResults.push(matchingPost);
- }
- }
- };
- for (var i = 0; i < data.length; i++) loop( i );
- return matchingResults.sort(function (r1, r2) { return r2.score - r1.score; });
- }
- function init(config, vm) {
- var isAuto = config.paths === 'auto';
- var paths = isAuto ? getAllPaths(vm.router) : config.paths;
- var namespaceSuffix = '';
- // only in auto mode
- if (paths.length && isAuto && config.pathNamespaces) {
- var path = paths[0];
- if (Array.isArray(config.pathNamespaces)) {
- namespaceSuffix =
- config.pathNamespaces.filter(
- function (prefix) { return path.slice(0, prefix.length) === prefix; }
- )[0] || namespaceSuffix;
- } else if (config.pathNamespaces instanceof RegExp) {
- var matches = path.match(config.pathNamespaces);
- if (matches) {
- namespaceSuffix = matches[0];
- }
- }
- var isExistHome = paths.indexOf(namespaceSuffix + '/') === -1;
- var isExistReadme = paths.indexOf(namespaceSuffix + '/README') === -1;
- if (isExistHome && isExistReadme) {
- paths.unshift(namespaceSuffix + '/');
- }
- } else if (paths.indexOf('/') === -1 && paths.indexOf('/README') === -1) {
- paths.unshift('/');
- }
- var expireKey = resolveExpireKey(config.namespace) + namespaceSuffix;
- var indexKey = resolveIndexKey(config.namespace) + namespaceSuffix;
- var isExpired = localStorage.getItem(expireKey) < Date.now();
- INDEXS = JSON.parse(localStorage.getItem(indexKey));
- if (isExpired) {
- INDEXS = {};
- } else if (!isAuto) {
- return;
- }
- var len = paths.length;
- var count = 0;
- paths.forEach(function (path) {
- if (INDEXS[path]) {
- return count++;
- }
- Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then(
- function (result) {
- INDEXS[path] = genIndex(path, result, vm.router, config.depth);
- len === ++count && saveData(config.maxAge, expireKey, indexKey);
- }
- );
- });
- }
- /* eslint-disable no-unused-vars */
- var NO_DATA_TEXT = '';
- var options;
- function style() {
- var code = "\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0 7px;\n line-height: 36px;\n font-size: 14px;\n border: 1px solid transparent;\n}\n\n.search input:focus {\n box-shadow: 0 0 5px var(--theme-color, #42b983);\n border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.search .clear-button {\n cursor: pointer;\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}";
- Docsify.dom.style(code);
- }
- function tpl(defaultValue) {
- if ( defaultValue === void 0 ) defaultValue = '';
- var html = "<div class=\"input-wrap\">\n <input type=\"search\" value=\"" + defaultValue + "\" aria-label=\"Search text\" />\n <div class=\"clear-button\">\n <svg width=\"26\" height=\"24\">\n <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#ccc\" />\n <path stroke=\"white\" stroke-width=\"2\" d=\"M8.25,8.25,15.75,15.75\" />\n <path stroke=\"white\" stroke-width=\"2\"d=\"M8.25,15.75,15.75,8.25\" />\n </svg>\n </div>\n </div>\n <div class=\"results-panel\"></div>\n </div>";
- var el = Docsify.dom.create('div', html);
- var aside = Docsify.dom.find('aside');
- Docsify.dom.toggleClass(el, 'search');
- Docsify.dom.before(aside, el);
- }
- function doSearch(value) {
- var $search = Docsify.dom.find('div.search');
- var $panel = Docsify.dom.find($search, '.results-panel');
- var $clearBtn = Docsify.dom.find($search, '.clear-button');
- var $sidebarNav = Docsify.dom.find('.sidebar-nav');
- var $appName = Docsify.dom.find('.app-name');
- if (!value) {
- $panel.classList.remove('show');
- $clearBtn.classList.remove('show');
- $panel.innerHTML = '';
- if (options.hideOtherSidebarContent) {
- $sidebarNav && $sidebarNav.classList.remove('hide');
- $appName && $appName.classList.remove('hide');
- }
- return;
- }
- var matchs = search(value);
- var html = '';
- matchs.forEach(function (post) {
- html += "<div class=\"matching-post\">\n<a href=\"" + (post.url) + "\">\n<h2>" + (post.title) + "</h2>\n<p>" + (post.content) + "</p>\n</a>\n</div>";
- });
- $panel.classList.add('show');
- $clearBtn.classList.add('show');
- $panel.innerHTML = html || ("<p class=\"empty\">" + NO_DATA_TEXT + "</p>");
- if (options.hideOtherSidebarContent) {
- $sidebarNav && $sidebarNav.classList.add('hide');
- $appName && $appName.classList.add('hide');
- }
- }
- function bindEvents() {
- var $search = Docsify.dom.find('div.search');
- var $input = Docsify.dom.find($search, 'input');
- var $inputWrap = Docsify.dom.find($search, '.input-wrap');
- var timeId;
- /**
- Prevent to Fold sidebar.
- When searching on the mobile end,
- the sidebar is collapsed when you click the INPUT box,
- making it impossible to search.
- */
- Docsify.dom.on(
- $search,
- 'click',
- function (e) { return ['A', 'H2', 'P', 'EM'].indexOf(e.target.tagName) === -1 &&
- e.stopPropagation(); }
- );
- Docsify.dom.on($input, 'input', function (e) {
- clearTimeout(timeId);
- timeId = setTimeout(function (_) { return doSearch(e.target.value.trim()); }, 100);
- });
- Docsify.dom.on($inputWrap, 'click', function (e) {
- // Click input outside
- if (e.target.tagName !== 'INPUT') {
- $input.value = '';
- doSearch();
- }
- });
- }
- function updatePlaceholder(text, path) {
- var $input = Docsify.dom.getNode('.search input[type="search"]');
- if (!$input) {
- return;
- }
- if (typeof text === 'string') {
- $input.placeholder = text;
- } else {
- var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
- $input.placeholder = text[match];
- }
- }
- function updateNoData(text, path) {
- if (typeof text === 'string') {
- NO_DATA_TEXT = text;
- } else {
- var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
- NO_DATA_TEXT = text[match];
- }
- }
- function updateOptions(opts) {
- options = opts;
- }
- function init$1(opts, vm) {
- var keywords = vm.router.parse().query.s;
- updateOptions(opts);
- style();
- tpl(keywords);
- bindEvents();
- keywords && setTimeout(function (_) { return doSearch(keywords); }, 500);
- }
- function update(opts, vm) {
- updateOptions(opts);
- updatePlaceholder(opts.placeholder, vm.route.path);
- updateNoData(opts.noData, vm.route.path);
- }
- /* eslint-disable no-unused-vars */
- var CONFIG = {
- placeholder: 'Type to search',
- noData: 'No Results!',
- paths: 'auto',
- depth: 2,
- maxAge: 86400000, // 1 day
- hideOtherSidebarContent: false,
- namespace: undefined,
- pathNamespaces: undefined,
- };
- var install = function(hook, vm) {
- var util = Docsify.util;
- var opts = vm.config.search || CONFIG;
- if (Array.isArray(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.pathNamespaces = opts.pathNamespaces || CONFIG.pathNamespaces;
- }
- var isAuto = CONFIG.paths === 'auto';
- hook.mounted(function (_) {
- init$1(CONFIG, vm);
- !isAuto && init(CONFIG, vm);
- });
- hook.doneEach(function (_) {
- update(CONFIG, vm);
- isAuto && init(CONFIG, vm);
- });
- };
- $docsify.plugins = [].concat(install, $docsify.plugins);
- }());
|