summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2016-09-21 15:54:58 +0200
committerSamy Pesse <samypesse@gmail.com>2016-09-21 15:54:58 +0200
commita18370551a1c3b9649d96199418251d3b6aaac24 (patch)
treea8ba076836695cd645ac795bf153873f3d3f42e2
parenta8aeab17d6ac2808f0fd6d6cff1626058c5323fe (diff)
downloadgitbook-a18370551a1c3b9649d96199418251d3b6aaac24.zip
gitbook-a18370551a1c3b9649d96199418251d3b6aaac24.tar.gz
gitbook-a18370551a1c3b9649d96199418251d3b6aaac24.tar.bz2
Prepare showing page html
-rw-r--r--packages/gitbook-core/package.json2
-rw-r--r--packages/gitbook-core/src/actions/TYPES.js7
-rw-r--r--packages/gitbook-core/src/actions/navigation.js14
-rw-r--r--packages/gitbook-core/src/components/HTMLContent.js59
-rw-r--r--packages/gitbook-core/src/components/InjectedComponent.js15
-rw-r--r--packages/gitbook-core/src/components/UnsafeComponent.js29
-rw-r--r--packages/gitbook-core/src/index.js11
-rw-r--r--packages/gitbook-core/src/reducers/index.js10
-rw-r--r--packages/gitbook-core/src/reducers/navigation.js35
-rw-r--r--packages/gitbook-core/src/shapes/Page.js11
-rw-r--r--packages/gitbook-core/src/shapes/index.js4
-rw-r--r--packages/gitbook-plugin-theme-default/src/Page.js20
-rw-r--r--packages/gitbook-plugin-theme-default/src/Sidebar.js13
-rw-r--r--packages/gitbook-plugin-theme-default/src/index.js23
-rw-r--r--packages/gitbook/src/browser/render.js2
-rw-r--r--packages/gitbook/src/output/website/copyPluginAssets.js34
16 files changed, 251 insertions, 38 deletions
diff --git a/packages/gitbook-core/package.json b/packages/gitbook-core/package.json
index 387a610..caf2fe2 100644
--- a/packages/gitbook-core/package.json
+++ b/packages/gitbook-core/package.json
@@ -4,11 +4,13 @@
"description": "Core for GitBook plugins API",
"main": "./lib/index.js",
"dependencies": {
+ "html-tags": "^1.1.1",
"immutable": "^3.8.1",
"react": "^15.3.1",
"react-dom": "^15.3.1",
"react-helmet": "^3.1.0",
"react-redux": "^4.4.5",
+ "react-safe-html": "^0.3.0",
"redux": "^3.5.2",
"redux-thunk": "^2.1.0"
},
diff --git a/packages/gitbook-core/src/actions/TYPES.js b/packages/gitbook-core/src/actions/TYPES.js
index b5c4b43..510c1d9 100644
--- a/packages/gitbook-core/src/actions/TYPES.js
+++ b/packages/gitbook-core/src/actions/TYPES.js
@@ -1,5 +1,10 @@
module.exports = {
+ // Components
REGISTER_COMPONENT: 'components:register',
- UNREGISTER_COMPONENT: 'components:unregister'
+ UNREGISTER_COMPONENT: 'components:unregister',
+ //Navigation
+ PAGE_FETCH_START: 'navigation:fetch:start',
+ PAGE_FETCH_END: 'navigation:fetch:end',
+ PAGE_FETCH_ERROR: 'navigation:fetch:error'
};
diff --git a/packages/gitbook-core/src/actions/navigation.js b/packages/gitbook-core/src/actions/navigation.js
new file mode 100644
index 0000000..a467d23
--- /dev/null
+++ b/packages/gitbook-core/src/actions/navigation.js
@@ -0,0 +1,14 @@
+
+
+/**
+ * Fetch a new page and update the store accordingly
+ */
+function fetchPage(uri) {
+ return (dispatch, getState) => {
+
+ };
+}
+
+module.exports = {
+ fetchPage
+};
diff --git a/packages/gitbook-core/src/components/HTMLContent.js b/packages/gitbook-core/src/components/HTMLContent.js
new file mode 100644
index 0000000..979fe0c
--- /dev/null
+++ b/packages/gitbook-core/src/components/HTMLContent.js
@@ -0,0 +1,59 @@
+const React = require('react');
+const ReactSafeHtml = require('react-safe-html');
+const htmlTags = require('html-tags');
+
+const { InjectedComponent } = require('./InjectedComponent');
+
+/*
+ HTMLContent is a container for the page HTML that parse the content and
+ render the right block.
+ All html elements can be extended using the injected component.
+ */
+
+function inject(injectedProps, Component) {
+ return (props) => {
+ return (
+ <InjectedComponent {...injectedProps(props)}>
+ <Component {...props} />
+ </InjectedComponent>
+ );
+ };
+}
+
+const COMPONENTS = {
+ // Templating blocks are exported as <template-block block="youtube" props="{}" />
+ 'template-block': inject(
+ ({block, props}) => {
+ return {
+ matching: { role: `block:${block}` },
+ props: JSON.parse(props)
+ };
+ },
+ props => <div {...props} />
+ )
+};
+
+htmlTags.forEach(tag => {
+ COMPONENTS[tag] = inject(
+ props => {
+ return {
+ matching: { role: `html:${tag}` },
+ props
+ };
+ },
+ props => React.createElement(tag, props)
+ );
+});
+
+const HTMLContent = React.createClass({
+ propTypes: {
+ html: React.PropTypes.string.isRequired
+ },
+
+ render() {
+ const { html } = this.props;
+ return <ReactSafeHtml html={html} components={COMPONENTS} />;
+ }
+});
+
+module.exports = HTMLContent;
diff --git a/packages/gitbook-core/src/components/InjectedComponent.js b/packages/gitbook-core/src/components/InjectedComponent.js
index d62799b..2acc5db 100644
--- a/packages/gitbook-core/src/components/InjectedComponent.js
+++ b/packages/gitbook-core/src/components/InjectedComponent.js
@@ -63,17 +63,20 @@ function mapStateToProps(state, props) {
const { components } = state;
const { matching } = props;
+ console.log('get components matching', matching);
return {
components: findMatchingComponents(components, matching)
};
}
+const InjectedComponent = ReactRedux.connect((state, props) => {
+ const result = mapStateToProps(state, props);
+ result.components = result.components.slice(0, 1);
+ result.withContainer = false;
+ return result;
+})(InjectedComponentSet);
+
module.exports = {
- InjectedComponent: ReactRedux.connect((state, props) => {
- const result = mapStateToProps(state, props);
- result.components = result.components.slice(0, 1);
- result.withContainer = false;
- return result;
- })(InjectedComponentSet),
+ InjectedComponent,
InjectedComponentSet: ReactRedux.connect(mapStateToProps)(InjectedComponentSet)
};
diff --git a/packages/gitbook-core/src/components/UnsafeComponent.js b/packages/gitbook-core/src/components/UnsafeComponent.js
index e9d2895..81ec239 100644
--- a/packages/gitbook-core/src/components/UnsafeComponent.js
+++ b/packages/gitbook-core/src/components/UnsafeComponent.js
@@ -3,6 +3,8 @@ const React = require('react');
const ReactDOM = require('react-dom');
const ReactRedux = require('react-redux');
+const isServerSide = typeof window === 'undefined';
+
/*
Public: Renders a component provided via the `component` prop, and ensures that
failures in the component's code do not cause state inconsistencies elsewhere in
@@ -22,6 +24,9 @@ const UnsafeComponent = React.createClass({
Component: React.PropTypes.func.isRequired,
props: React.PropTypes.object
},
+ contextTypes: {
+ store: React.PropTypes.object
+ },
componentDidMount() {
return this.renderInjected();
@@ -35,18 +40,22 @@ const UnsafeComponent = React.createClass({
return this.unmountInjected();
},
- renderInjected() {
+ getInjected() {
const { Component, props } = this.props;
const { store } = this.context;
+ return (
+ <ReactRedux.Provider store={store}>
+ <Component {...props}/>
+ </ReactRedux.Provider>
+ );
+ },
+
+ renderInjected() {
const node = ReactDOM.findDOMNode(this);
try {
- this.injected = (
- <ReactRedux.Provider store={store}>
- <Component {...props}/>
- </ReactRedux.Provider>
- );
+ this.injected = this.getInjected();
ReactDOM.render(this.injected, node);
} catch (err) {
@@ -76,7 +85,13 @@ const UnsafeComponent = React.createClass({
},
render() {
- return <div name="unsafe-component-wrapper" />;
+ let inner;
+
+ if (isServerSide) {
+ inner = this.getInjected();
+ }
+
+ return <div name="unsafe-component-wrapper">{inner}</div>;
}
});
diff --git a/packages/gitbook-core/src/index.js b/packages/gitbook-core/src/index.js
index 84dcd47..9b29c91 100644
--- a/packages/gitbook-core/src/index.js
+++ b/packages/gitbook-core/src/index.js
@@ -1,7 +1,12 @@
const Head = require('react-helmet');
+
const { InjectedComponent, InjectedComponentSet } = require('./components/InjectedComponent');
+const HTMLContent = require('./components/HTMLContent');
+
const { registerComponent } = require('./actions/components');
const ACTIONS = require('./actions/TYPES');
+
+const Shapes = require('./shapes');
const connect = require('./connect');
const createPlugin = require('./createPlugin');
const createReducer = require('./createReducer');
@@ -16,7 +21,11 @@ module.exports = {
createStore,
renderComponent,
registerComponent,
+ // React Components
InjectedComponent,
InjectedComponentSet,
- Head
+ HTMLContent,
+ Head,
+ // Utilities
+ Shapes
};
diff --git a/packages/gitbook-core/src/reducers/index.js b/packages/gitbook-core/src/reducers/index.js
index 05ff70f..dae1f9c 100644
--- a/packages/gitbook-core/src/reducers/index.js
+++ b/packages/gitbook-core/src/reducers/index.js
@@ -1,5 +1,13 @@
const Redux = require('redux');
+const identity = ((state, action) => state || {});
+
module.exports = Redux.combineReducers({
- components: require('./components')
+ components: require('./components'),
+ navigation: require('./navigation'),
+
+ // GitBook JSON
+ page: identity,
+ summary: identity,
+ readme: identity
});
diff --git a/packages/gitbook-core/src/reducers/navigation.js b/packages/gitbook-core/src/reducers/navigation.js
new file mode 100644
index 0000000..a895186
--- /dev/null
+++ b/packages/gitbook-core/src/reducers/navigation.js
@@ -0,0 +1,35 @@
+const { Record } = require('immutable');
+const ACTION_TYPES = require('../actions/TYPES');
+
+const NavigationState = Record({
+ loading: false,
+ error: null
+});
+
+function reduceNavigation(state, action) {
+ state = state || NavigationState();
+ switch (action.type) {
+
+ case ACTION_TYPES.PAGE_FETCH_START:
+ return state.merge({
+ loading: true
+ });
+
+ case ACTION_TYPES.PAGE_FETCH_END:
+ return state.merge({
+ loading: false
+ });
+
+ case ACTION_TYPES.PAGE_FETCH_ERROR:
+ return state.merge({
+ loading: false,
+ error: action.error
+ });
+
+ default:
+ return state;
+
+ }
+}
+
+module.exports = reduceNavigation;
diff --git a/packages/gitbook-core/src/shapes/Page.js b/packages/gitbook-core/src/shapes/Page.js
new file mode 100644
index 0000000..11117fe
--- /dev/null
+++ b/packages/gitbook-core/src/shapes/Page.js
@@ -0,0 +1,11 @@
+const React = require('react');
+const {
+ string,
+ shape
+} = React.PropTypes;
+
+
+module.exports = shape({
+ title: string.isRequired,
+ content: string.isRequired
+});
diff --git a/packages/gitbook-core/src/shapes/index.js b/packages/gitbook-core/src/shapes/index.js
new file mode 100644
index 0000000..ca95a99
--- /dev/null
+++ b/packages/gitbook-core/src/shapes/index.js
@@ -0,0 +1,4 @@
+
+module.exports = {
+ Page: require('./Page')
+};
diff --git a/packages/gitbook-plugin-theme-default/src/Page.js b/packages/gitbook-plugin-theme-default/src/Page.js
new file mode 100644
index 0000000..dda8eba
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/Page.js
@@ -0,0 +1,20 @@
+const React = require('react');
+const GitBook = require('gitbook-core');
+
+const Page = React.createClass({
+ propTypes: {
+ page: GitBook.Shapes.Page
+ },
+
+ render() {
+ const { page } = this.props;
+
+ return (
+ <div className="Page page-wrapper">
+ <GitBook.HTMLContent html={page.content} />
+ </div>
+ );
+ }
+});
+
+module.exports = Page;
diff --git a/packages/gitbook-plugin-theme-default/src/Sidebar.js b/packages/gitbook-plugin-theme-default/src/Sidebar.js
new file mode 100644
index 0000000..2ff8854
--- /dev/null
+++ b/packages/gitbook-plugin-theme-default/src/Sidebar.js
@@ -0,0 +1,13 @@
+const React = require('react');
+
+const Sidebar = React.createClass({
+ render() {
+ return (
+ <div className="Sidebar book-summary">
+
+ </div>
+ );
+ }
+});
+
+module.exports = Sidebar;
diff --git a/packages/gitbook-plugin-theme-default/src/index.js b/packages/gitbook-plugin-theme-default/src/index.js
index 3630bbe..f85e6bc 100644
--- a/packages/gitbook-plugin-theme-default/src/index.js
+++ b/packages/gitbook-plugin-theme-default/src/index.js
@@ -1,21 +1,36 @@
const React = require('react');
const GitBook = require('gitbook-core');
-const ThemeBody = React.createClass({
+const Sidebar = require('./Sidebar');
+const Page = require('./Page');
+
+let ThemeBody = React.createClass({
+ propTypes: {
+ page: GitBook.Shapes.Page
+ },
+
render() {
+ const { page } = this.props;
+
+ console.log('render theme', page);
return (
- <div>
+ <div className="GitBook book">
<GitBook.Head
- title={'Homepage'}
+ title={page.title}
titleTemplate="%s - GitBook"
/>
- My Base theme for gitbook
+ <Sidebar />
+ <Page page={page} />
</div>
);
}
});
+ThemeBody = GitBook.connect(ThemeBody, ({page}) => {
+ return { page };
+});
+
module.exports = GitBook.createPlugin((dispatch, state) => {
dispatch(GitBook.registerComponent(ThemeBody, { role: 'Body' }));
});
diff --git a/packages/gitbook/src/browser/render.js b/packages/gitbook/src/browser/render.js
index af71b87..9c2e065 100644
--- a/packages/gitbook/src/browser/render.js
+++ b/packages/gitbook/src/browser/render.js
@@ -15,7 +15,7 @@ function HTML({head, innerHTML, props}) {
</head>
<body>
<div id="content" dangerouslySetInnerHTML={{__html: innerHTML}} />
- {head.link.toComponent()}
+ {head.script.toComponent()}
<script
type="application/payload+json"
dangerouslySetInnerHTML={{__html: propsJSON}} />
diff --git a/packages/gitbook/src/output/website/copyPluginAssets.js b/packages/gitbook/src/output/website/copyPluginAssets.js
index 315804a..312d3d6 100644
--- a/packages/gitbook/src/output/website/copyPluginAssets.js
+++ b/packages/gitbook/src/output/website/copyPluginAssets.js
@@ -5,13 +5,13 @@ const Promise = require('../../utils/promise');
const fs = require('../../utils/fs');
/**
- Copy all assets from plugins.
- Assets are files stored in "_assets"
- nd resources declared in the plugin itself.
-
- @param {Output}
- @return {Promise}
-*/
+ * Copy all assets from plugins.
+ * Assets are files stored in "_assets"
+ * and resources declared in the plugin itself.
+ *
+ * @param {Output}
+ * @return {Promise}
+ */
function copyPluginAssets(output) {
const book = output.getBook();
@@ -37,11 +37,11 @@ function copyPluginAssets(output) {
}
/**
- Copy assets from a plugin
-
- @param {Plugin}
- @return {Promise}
-*/
+ * Copy assets from a plugin
+ *
+ * @param {Plugin}
+ * @return {Promise}
+ */
function copyAssets(output, plugin) {
const logger = output.getLogger();
const pluginRoot = plugin.getPath();
@@ -70,11 +70,11 @@ function copyAssets(output, plugin) {
}
/**
- Copy resources from a plugin
-
- @param {Plugin}
- @return {Promise}
-*/
+ * Copy resources from a plugin
+ *
+ * @param {Plugin}
+ * @return {Promise}
+ */
function copyResources(output, plugin) {
const logger = output.getLogger();