Fix query action for search

This commit is contained in:
Samy Pesse
2016-09-29 19:04:56 +02:00
parent 6015defe11
commit 9d8dffb6f0
10 changed files with 218 additions and 9 deletions
+2 -1
View File
@@ -17,7 +17,8 @@
"react-safe-html": "^0.3.0",
"redux": "^3.5.2",
"redux-thunk": "^2.1.0",
"reflexbox": "^2.2.2"
"reflexbox": "^2.2.2",
"whatwg-fetch": "^1.0.0"
},
"devDependencies": {
"babel-cli": "^6.14.0",
+2
View File
@@ -1,3 +1,5 @@
require('whatwg-fetch');
const React = require('react');
const Immutable = require('immutable');
const Head = require('react-helmet');
@@ -40,7 +40,7 @@ function createContext(plugins, initialState) {
// Initialize the plugins
plugins.forEach(plugin => {
plugin.init(store.dispatch, store.getState);
plugin.init(store.dispatch, store.getState, actions);
});
return GitBookContext({
+31
View File
@@ -0,0 +1,31 @@
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
# vim swapfile
*.swp
# Plugin assets
_assets
+2
View File
@@ -0,0 +1,2 @@
# Publish assets on NPM
!_assets
+97
View File
@@ -0,0 +1,97 @@
/* eslint-disable no-var, object-shorthand */
var lunr = require('lunr');
var Entities = require('html-entities').AllHtmlEntities;
var Html = new Entities();
var searchIndex;
// Called with the `this` context provided by Gitbook
function getSearchIndex(context) {
if (!searchIndex) {
// Create search index
var ignoreSpecialCharacters = (
context.config.get('pluginsConfig.lunr.ignoreSpecialCharacters')
|| context.config.get('lunr.ignoreSpecialCharacters')
);
searchIndex = lunr(function() {
this.ref('url');
this.field('title', { boost: 10 });
this.field('keywords', { boost: 15 });
this.field('body');
if (!ignoreSpecialCharacters) {
// Don't trim non words characters (to allow search such as "C++")
this.pipeline.remove(lunr.trimmer);
}
});
}
return searchIndex;
}
// Map of Lunr ref to document
var documentsStore = {};
var searchIndexEnabled = true;
var indexSize = 0;
module.exports = {
hooks: {
// Index each page
'page': function(page) {
if (this.output.name != 'website' || !searchIndexEnabled || page.search === false) {
return page;
}
var text, maxIndexSize;
maxIndexSize = this.config.get('pluginsConfig.lunr.maxIndexSize') || this.config.get('lunr.maxIndexSize');
this.log.debug.ln('index page', page.path);
text = page.content;
// Decode HTML
text = Html.decode(text);
// Strip HTML tags
text = text.replace(/(<([^>]+)>)/ig, '');
indexSize = indexSize + text.length;
if (indexSize > maxIndexSize) {
this.log.warn.ln('search index is too big, indexing is now disabled');
searchIndexEnabled = false;
return page;
}
var keywords = [];
if (page.search) {
keywords = page.search.keywords || [];
}
// Add to index
var doc = {
url: this.output.toURL(page.path),
title: page.title,
summary: page.description,
keywords: keywords.join(' '),
body: text
};
documentsStore[doc.url] = doc;
getSearchIndex(this).add(doc);
return page;
},
// Write index to disk
'finish': function() {
if (this.output.name != 'website') return;
this.log.debug.ln('write search index');
return this.output.writeFile('search_index.json', JSON.stringify({
index: getSearchIndex(this),
store: documentsStore
}));
}
}
};
+44
View File
@@ -0,0 +1,44 @@
{
"name": "gitbook-plugin-lunr",
"description": "Static and local index for search in GitBook",
"main": "index.js",
"browser": "./_assets/theme.js",
"version": "1.2.0",
"dependencies": {
"gitbook-core": "^0.0.0",
"html-entities": "1.2.0",
"lunr": "0.5.12"
},
"devDependencies": {
"gitbook-plugin": "*"
},
"engines": {
"gitbook": ">=3.0.0"
},
"gitbook": {
"properties": {
"maxIndexSize": {
"type": "number",
"title": "Limit size for the index",
"default": 1000000
},
"ignoreSpecialCharacters": {
"type": "boolean",
"title": "Ignore special characters in words",
"default": false
}
}
},
"scripts": {
"build-js": "gitbook-plugin build ./src/index.js ./_assets/theme.js",
"prepublish": "npm run build-js"
},
"homepage": "https://github.com/GitBookIO/gitbook",
"repository": {
"type": "git",
"url": "https://github.com/GitBookIO/gitbook.git"
},
"bugs": {
"url": "https://github.com/GitBookIO/gitbook/issues"
}
}
+21
View File
@@ -0,0 +1,21 @@
const GitBook = require('gitbook-core');
const lunr = require('lunr');
/**
* Search in the local index
* @param {String} query
* @return {Promise<List>}
*/
function searchHandler(query) {
return [
{ title: 'Hello world' }
];
}
module.exports = GitBook.createPlugin({
init: (dispatch, getState, actions) => {
const { search } = actions;
dispatch(search.registerHandler('lunr', searchHandler));
},
reduce: (state, action) => state
});
@@ -17,13 +17,19 @@ function query(q) {
dispatch({ type: TYPES.UPDATE_QUERY, query: q });
return Promise.reduce(handlers, (results, handler) => {
return Promise(handler(q))
.then(handlerResults => results.concat(handlerResults));
}, List())
.then(results => {
dispatch({ type: TYPES.UPDATE_RESULTS, query: q });
});
return Promise.reduce(
handlers.toArray(),
(results, handler) => {
return Promise.resolve(handler(q))
.then(handlerResults => results.concat(handlerResults));
},
List()
)
.then(
results => {
dispatch({ type: TYPES.UPDATE_RESULTS, query: q, results });
}
);
};
}
@@ -23,6 +23,11 @@ module.exports = (state = SearchState(), action) => {
query: action.query
});
case TYPES.UPDATE_RESULTS:
return state.merge({
results: action.results
});
case TYPES.REGISTER_HANDLER:
return state.merge({
handlers: state.handlers.set(action.name, action.handler)