diff --git a/index.html b/index.html
index 9f443671b..1fffd6684 100644
--- a/index.html
+++ b/index.html
@@ -41,7 +41,7 @@
maxLevel: 4,
subMaxLevel: 2,
name: 'docsify',
- search: {
+ /*search: {
noData: {
'/de-de/': 'Keine Ergebnisse!',
'/zh-cn/': '没有结果!',
@@ -52,10 +52,11 @@
'/de-de/': 'Suche',
'/zh-cn/': '搜索',
'/': 'Search'
- },
+ },*/
pathNamespaces: ['/zh-cn', '/de-de', '/ru-ru', '/es']
},
plugins: [
+ fullTextSearch,
function (hook, vm) {
hook.beforeEach(function (html) {
if (/githubusercontent\.com/.test(vm.route.file)) {
diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js
index 6a212c016..2ee6bd53f 100644
--- a/src/plugins/search/search.js
+++ b/src/plugins/search/search.js
@@ -1,250 +1,338 @@
-/* eslint-disable no-unused-vars */
-import { getAndRemoveConfig } from '../../core/render/utils';
+const paths = {}
+const promises = []
+// const NO_DATA_TEXT = "Sonuç bulunamadı ..."
+// var ResultColor = 'yellow'
+
+const configs = {
+ NO_DATA_TEXT: 'Nothing Found ...',
+ RESULT_COLOR: 'yellow',
+}
+
+function CreateSearchComponent () {
+ const code = `
+ .sidebar {
+ padding-top: 0;
+ }
+ .search {
+ margin-bottom: 20px;
+ padding: 6px;
+ border-bottom: 1px solid #eee;
+ }
+ .search .input-wrap {
+ display: flex;
+ align-items: center;
+ }
+ .search .results-panel {
+ display: none;
+ }
+ .search .results-panel.show {
+ display: block;
+ }
+ .search input {
+ outline: none;
+ border: none;
+ width: 100%;
+ padding: 0 7px;
+ line-height: 36px;
+ font-size: 14px;
+ border: 1px solid transparent;
+ }
+ .search input:focus {
+ box-shadow: 0 0 5px var(--theme-color, #42b983);
+ border: 1px solid var(--theme-color, #42b983);
+ }
+ .search input::-webkit-search-decoration,
+ .search input::-webkit-search-cancel-button,
+ .search input {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ }
+ .search .clear-button {
+ cursor: pointer;
+ width: 36px;
+ text-align: right;
+ display: none;
+ }
+ .search .clear-button.show {
+ display: block;
+ }
+ .search .clear-button svg {
+ transform: scale(.5);
+ }
+ .search h2 {
+ font-size: 17px;
+ margin: 10px 0;
+ }
+ .search a {
+ text-decoration: none;
+ color: inherit;
+ }
+ .search .matching-post {
+ border-bottom: 1px solid #eee;
+ }
+ .search .matching-post:last-child {
+ border-bottom: 0;
+ }
+ .search p {
+ font-size: 12px !important;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 4;
+ -webkit-box-orient: vertical;
+ }
+ .search p.empty {
+ text-align: center;
+ }
+ .app-name.hide, .sidebar-nav.hide {
+ display: none;
+ }
-let INDEXS = {};
+ .lbC {
+ background-color: yellow;
+ }
-const LOCAL_STORAGE = {
- EXPIRE_KEY: 'docsify.search.expires',
- INDEX_KEY: 'docsify.search.index',
-};
+ `
+ const search = Docsify.dom.find('.search')
+ if (!search) {
+ Docsify.dom.style(code)
+ const search = 'Arama ...'
+ const html = `
+
+ `
+ const el = Docsify.dom.create('div', html)
+ const aside = Docsify.dom.find('aside')
+
+ Docsify.dom.toggleClass(el, 'search')
+ Docsify.dom.before(aside, el)
+ bindEvents()
+ }
-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 bindEvents () {
+ const $search = Docsify.dom.find('div.search')
+ const $input = Docsify.dom.find($search, 'input')
+ const $inputWrap = Docsify.dom.find($search, '.input-wrap')
+ let timeId
+ Docsify.dom.on($input, 'input', e => {
+ clearTimeout(timeId)
+ timeId = setTimeout(() => SearchInputOnPage(e.target.value.trim()) /* ListSearcMatches(e.target.value.trim())*/, 400)
+ })
+ Docsify.dom.on($inputWrap, 'click', e => {
+ // Click input outside
+ if (e.target.tagName !== 'INPUT') {
+ $input.value = ''
+ SearchInputOnPage(null)
+ // ClearLabelStyle()
+ } else if (!$input.value)
+ ClearLabelStyle()
+
+ })
}
-function escapeHtml(string) {
- const entityMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- };
-
- return String(string).replace(/[&<>"']/g, s => entityMap[s]);
+function ClearLabelStyle () {
+ console.log('ClearLabelStyle tetiklendi')
+ const labels = document.querySelectorAll('label')
+ for (let i = 0; i < labels.length; i++)
+ labels[i].style = ''
}
-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);
- }
- });
-
- return paths;
+function ClickToSearchResult (e) {
+ localStorage.setItem('searcIndex', e.attributes.data.nodeValue)
+ if (window.location == e.href) {
+ console.log(window.location, e.href)
+ ScroolToResult()
+ }
}
-function getTableData(token) {
- if (!token.text && token.type === 'table') {
- token.cells.unshift(token.header);
- token.text = token.cells
- .map(function(rows) {
- return rows.join(' | ');
- })
- .join(' |\n ');
- }
- return token.text;
-}
+function SearchInputOnPage (searchKey) {
+ // Invoked each time after the data is fully loaded, no arguments,
+ if (searchKey) {
+ Docsify.dom
+ .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])')
+ .forEach(item => {
+ promises.push(new Promise(res => {
+ const page = item.href
+ const url = page.replace(/\/\#\//, '/') + '.md'
+ if (url.indexOf('/.md') === -1)
+ GetMDFiles(url, page, item.innerText, paths, res)
+ else
+ res(true)
+ }))
+ })
+ console.log(paths)
+
+ Promise.all(promises).then(() => {
+ const keys = Object.keys(paths)
+ // const searchKey = 'pointObj'
+ localStorage.setItem('regex', '(.{30}|.)' + searchKey + '(.{30}|.)')
+ localStorage.setItem('searchKey', searchKey)
+ const re = new RegExp('(.{30}|.)' + searchKey + '(.{30}|.)', 'g')
+ const storageData = []
+ let found
+ for (let i = keys.length; i--;) {
+ found = paths[keys[i]].data.match(re)
+ if (found)
+ storageData.push({
+ url: paths[keys[i]].page,
+ title: paths[keys[i]].title,
+ key: searchKey,
+ results: found,
+ })
+
+ }
+ // if(data.length){
+ // localStorage.setItem('searchData',JSON.stringify(storageData))
+ // }
+ return storageData
+ })
+ .then(matches => {
+ console.log('isteklerden sonra: ', matches)
+ ListSearcMatches(matches)
+ ScroolToResult()
+ })
+ } else
+ ListSearcMatches([])
-function saveData(maxAge, expireKey, indexKey) {
- 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;
-
- tokens.forEach(token => {
- if (token.type === 'heading' && token.depth <= depth) {
- const { str, config } = getAndRemoveConfig(token.text);
-
- if (config.id) {
- slug = router.toURL(path, { id: slugify(config.id) });
- } else {
- slug = router.toURL(path, { id: slugify(escapeHtml(token.text)) });
- }
-
- index[slug] = { slug, title: str, body: '' };
- } else {
- if (!slug) {
- return;
- }
-
- if (!index[slug]) {
- index[slug] = { slug, title: '', body: '' };
- } else if (index[slug].body) {
- token.text = getTableData(token);
-
- index[slug].body += '\n' + (token.text || '');
- } else {
- token.text = getTableData(token);
-
- index[slug].body = index[slug].body
- ? index[slug].body + token.text
- : token.text;
- }
- }
- });
- slugify.clear();
- return index;
}
-/**
- * @param {String} query Search query
- * @returns {Array} Array of results
- */
-export function search(query) {
- const matchingResults = [];
- let data = [];
- Object.keys(INDEXS).forEach(key => {
- data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page]));
- });
-
- query = query.trim();
- let keywords = query.split(/[\s\-,\\/]+/);
- if (keywords.length !== 1) {
- 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 || '';
-
- if (postTitle) {
- keywords.forEach(keyword => {
- // From https://github.com/sindresorhus/escape-string-regexp
- const regEx = new RegExp(
- keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'),
- 'gi'
- );
- let indexTitle = -1;
- let indexContent = -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;
- if (indexContent < 0) {
- indexContent = 0;
- }
-
- let start = 0;
- let end = 0;
-
- start = indexContent < 11 ? 0 : indexContent - 10;
- end = start === 0 ? 70 : indexContent + keyword.length + 60;
-
- if (postContent && end > postContent.length) {
- end = postContent.length;
- }
-
- const matchContent =
- '...' +
- escapeHtml(postContent)
- .substring(start, end)
- .replace(
- regEx,
- word => `${word}`
- ) +
- '...';
-
- resultStr += matchContent;
- }
- });
-
- if (matchesScore > 0) {
- const matchingPost = {
- title: escapeHtml(postTitle),
- content: postContent ? resultStr : '',
- url: postUrl,
- score: matchesScore,
- };
-
- matchingResults.push(matchingPost);
- }
- }
- }
-
- return matchingResults.sort((r1, r2) => r2.score - r1.score);
+function ListSearcMatches (matchs) {
+ const $search = Docsify.dom.find('div.search')
+ const $panel = Docsify.dom.find($search, '.results-panel')
+ const $clearBtn = Docsify.dom.find($search, '.clear-button')
+ // const $sidebarNav = Docsify.dom.find('.sidebar-nav')
+ // const $appName = Docsify.dom.find('.app-name')
+ if (!matchs.length) {
+ $panel.classList.remove('show')
+ $clearBtn.classList.remove('show')
+ $panel.innerHTML = ''
+ return
+ }
+ let html = ''
+ console.log(matchs)
+ matchs.forEach(post => {
+ console.log(post)
+ html += ``
+
+ post.results.forEach((res, i) => {
+ html += ``
+ })
+
+ })
+
+ $panel.classList.add('show')
+ $clearBtn.classList.add('show')
+ $panel.innerHTML = html || `${ configs.NO_DATA_TEXT }
`
+ // if (options.hideOtherSidebarContent) {
+ // $sidebarNav.classList.add('hide');
+ // $appName.classList.add('hide');
+ // }
}
-export function init(config, vm) {
- const isAuto = config.paths === 'auto';
- const paths = isAuto ? getAllPaths(vm.router) : config.paths;
+function GetMDFiles (url, page, title, obj, res) {
+ const http = new XMLHttpRequest()
+ http.onreadystatechange = function () {
+ if (this.readyState == 4 && this.status == 200) {
+ obj[url] = {
+ page,
+ data: http.responseText,
+ title,
+ }
+ res(true)
+ }
+ }
+ http.open('GET', url)
+ http.send()
+}
- let namespaceSuffix = '';
+function ScroolToResult () {
+ const itemIndex = parseInt(localStorage.getItem('searcIndex'))
+ console.log(itemIndex)
+ if (itemIndex != null) {
+ const main = document.getElementById('main')
+ const itemIndexInPage = 0
+ let item = null
+ for (let i = 0; i < main.children.length; i++) {
+ item = FindResultElem(main.children[i], itemIndexInPage, itemIndex)
+ if (item)
+ break
+
+ }
+ console.log('item', item)
+ if (item)
+ item.scrollIntoView({
+ behavior: 'smooth',
+ block: 'end',
+ inline: 'start',
+ })
+ }
- // only in auto mode
- if (isAuto && config.pathNamespaces) {
- const path = paths[0];
- if (Array.isArray(config.pathNamespaces)) {
- namespaceSuffix =
- config.pathNamespaces.find(prefix => path.startsWith(prefix)) ||
- namespaceSuffix;
- } else if (config.pathNamespaces instanceof RegExp) {
- const matches = path.match(config.pathNamespaces);
+}
- if (matches) {
- namespaceSuffix = matches[0];
- }
- }
- }
+function FindResultElem (item, itemIndexInPage, itemIndex) {
+ const searchKey = localStorage.getItem('searchKey')
+ if (searchKey) {
+ const re = new RegExp(searchKey, 'g')
+ const match = item.innerHTML.match(re)
+ console.log('match', match)
+ if (match) {
+ console.log(match, configs.RESULT_COLOR)
+ item.innerHTML = item.innerHTML.replace(re, ``)
+ itemIndexInPage += match.length
+ if (itemIndexInPage >= itemIndex) return item
+ }
+ } else
+ console.log('yokkk')
+
+ return null
+}
- const expireKey = resolveExpireKey(config.namespace) + namespaceSuffix;
- const indexKey = resolveIndexKey(config.namespace) + namespaceSuffix;
+function fullTextSearch (hook, vm) {
- const isExpired = localStorage.getItem(expireKey) < Date.now();
+ hook.init(() => {
+ localStorage.removeItem('searcIndex')
+ localStorage.removeItem('searchKey')
+ ClearLabelStyle()
+ })
- INDEXS = JSON.parse(localStorage.getItem(indexKey));
+ hook.beforeEach(content => {
+ })
- if (isExpired) {
- INDEXS = {};
- } else if (!isAuto) {
- return;
- }
+ hook.afterEach((html, next) => {
+ next(html)
+ })
- const len = paths.length;
- let count = 0;
+ hook.doneEach((x, vm) => {
+ CreateSearchComponent()
+ ScroolToResult()
+ })
- paths.forEach(path => {
- if (INDEXS[path]) {
- return count++;
- }
+ hook.mounted(() => {
+ })
- 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);
- }
- );
- });
+ hook.ready(() => {
+ })
}