diff --git a/build/generate-search-data.js b/build/generate-search-data.js
new file mode 100644
index 000000000..a3d7fe824
--- /dev/null
+++ b/build/generate-search-data.js
@@ -0,0 +1,39 @@
+/**
+ * @file 生成给前端全文搜索用的文件
+ * @author wuduoyi
+ */
+
+const glob = require('glob');
+const fs = require('fs');
+let yaml = require('js-yaml');
+var rYml = /^\s*---([\s\S]*?)---\s/;
+
+const resultData = {docs: []};
+
+glob('./docs/**/*.md', {}, function (er, docs) {
+ for (const doc of docs) {
+ let content = fs.readFileSync(doc, {encoding: 'utf8'});
+ let m = rYml.exec(content);
+ let info = {};
+ if (m && m[1]) {
+ info = yaml.safeLoad(m[1]);
+ content = content.substring(m[0].length);
+ }
+
+ const title = info.title || doc;
+ // todo: 属性列表单独处理,检索的时候优先检索
+ resultData.docs.push({
+ title: title,
+ // 去掉注释、换行、图片等
+ body: content
+ .replace(/<\!---.+-->/g, '')
+ .replace(/!?\[.*\]\(.*\)/g, '')
+ .replace(/\n/g, '')
+ .replace(/```.*```/g, '')
+
+ .toLowerCase(),
+ path: doc.replace('.md', '')
+ });
+ }
+ fs.writeFileSync('./gh-pages/docs/docs.json', JSON.stringify(resultData));
+});
diff --git a/deploy-gh-pages.sh b/deploy-gh-pages.sh
index 10d0f92c4..b27330a5d 100755
--- a/deploy-gh-pages.sh
+++ b/deploy-gh-pages.sh
@@ -1,10 +1,10 @@
#!/bin/bash
set -e
-if [ -z "$(git status --porcelain)" ]; then
+if [ -z "$(git status --porcelain)" ]; then
# Working directory clean
echo "Working directory clean"
-else
+else
# Uncommitted changes
read -p "You got uncommitted changes, press y to continue? " -n 1 -r
echo # (optional) move to a new line
@@ -21,6 +21,8 @@ fis3 release gh-pages -c
node ./build/upload2cdn.js $1
+node ./build/generate-search-data.js
+
git add gh-pages -f
git commit -m "更新 gh-pages"
@@ -33,4 +35,4 @@ git commit -m 'rebuild pages' --allow-empty
git push origin
-echo "done"
\ No newline at end of file
+echo "done"
diff --git a/examples/components/DocSearch.jsx b/examples/components/DocSearch.jsx
index 117f96f28..e9016929b 100644
--- a/examples/components/DocSearch.jsx
+++ b/examples/components/DocSearch.jsx
@@ -1,47 +1,79 @@
+/**
+ * @file 实现前端文档搜索
+ */
import React from 'react';
-import makeSchemaRenderer from './SchemaRender';
-
-const FormComponent = makeSchemaRenderer({
- type: 'form',
- mode: 'inline',
- wrapWithPanel: false,
- className: ':Doc-search',
- controls: [
- {
- type: 'input-group',
- size: 'sm',
- controls: [
- {
- type: 'icon',
- addOnclassName: 'no-bg no-border p-r-none p-l',
- className: 'text-sm',
- icon: 'search',
- vendor: 'iconfont'
- },
- {
- type: 'text',
- placeholder: '搜索...',
- inputClassName: 'no-border',
- name: 'docsearch'
- }
- ]
- }
- ]
-});
+import Axios from 'axios';
+import SearchBox from '../../src/components/SearchBox';
export default class DocSearch extends React.Component {
+ docs = [];
+ constructor(props) {
+ super(props);
+ this.state = {
+ searchResults: [],
+ loadError: false
+ };
+ this.onSearch = this.onSearch.bind(this);
+ this.onSearchCancel = this.onSearchCancel.bind(this);
+ }
componentDidMount() {
- // const inputSelector = 'input[name="docsearch"]';
- // docsearch({
- // appId: 'S08MJHBHFJ',
- // apiKey: '5fba814bb773d08b5d2a3f6074f926a5',
- // indexName: 'gh_pages',
- // inputSelector,
- // debug: false
- // });
+ Axios.get('/docs/docs.json')
+ .then(result => {
+ this.docs = result.data.docs;
+ })
+ .catch(err => {
+ this.setState({loadError: true});
+ });
+ }
+
+ onSearch(query) {
+ if (query === '') {
+ this.setState({searchResults: []});
+ return;
+ }
+ let results = [];
+ for (let doc of this.docs) {
+ let index = doc.body.indexOf(query);
+
+ if (index !== -1) {
+ results.push({
+ title: doc.title,
+ path: doc.path,
+ abstract: doc.body
+ .substring(Math.max(0, index - 20), index + 60)
+ .replace(query, `${query}`)
+ });
+ } else if (doc.title.indexOf(query) !== -1) {
+ results.push({
+ title: doc.title,
+ path: doc.path,
+ abstract: ''
+ });
+ }
+ }
+ this.setState({searchResults: results});
+ }
+
+ onSearchCancel() {
+ this.setState({searchResults: []});
}
render() {
- return