1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-20 15:32:09 +02:00

dual rendering possible using --singles

This commit is contained in:
Pomax
2016-01-16 17:57:16 -08:00
parent a346272dee
commit 819b628456
21 changed files with 4748 additions and 119 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,5 @@
var React = require("react"); var React = require("react");
var ReactDOM = require("react-dom"); var ReactDOM = require("react-dom");
var Article = require("./Article.jsx"); var FullArticle = require("./FullArticle.jsx");
var generateSingleSection = require("../pages/generateSingleSection");
require("../stylesheets/style.less"); ReactDOM.render(<FullArticle/>, document.getElementById("article"));
ReactDOM.render(<Article/>, document.getElementById("article"), function() {
// trigger a #hash navigation
if (window.location.hash) {
var hash = window.location.hash;
window.location.hash = hash;
}
});

View File

@@ -1,62 +0,0 @@
var React = require("react");
var ReactDOM = require("react-dom");
var Ribbon = require("./Ribbon.jsx");
var Article = React.createClass({
getInitialState: function() {
return {
sections: require("./sections")
};
},
setSectionId: function(name, entry) {
ReactDOM.findDOMNode(this.refs[name]).setAttribute("id", name);
},
componentDidMount: function() {
// Not sure why this doesn't just work by passing a props.id
this.sectionMap(this.setSectionId);
},
sectionMap: function(mapping) {
return this.getSectionNames().map(mapping);
},
getSectionNames: function() {
return Object.keys(this.state.sections);
},
generateSection: function(name, entry) {
var Type = this.state.sections[name];
return <Type key={name} ref={name} name={name} number={entry}/>;
},
generateNavItem: function(section, entry) {
var name = section.props.name;
var title = section.props.title;
return <li key={name} data-number={entry}><a href={'#' + name}>{ title }</a></li>;
},
render: function() {
var sections = this.sectionMap(this.generateSection);
return (<div>
<Ribbon />
<div ref="navigation">
<navigation>
<ul className="navigation">
{ sections.map(this.generateNavItem) }
</ul>
</navigation>
</div>
<div ref="sections">{ sections }</div>
<footer class="copyright">
This article is © 2011-2016 to me, Mike "Pomax" Kamermans, but the text, code,
and images are <a href="https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md">almost
no rights reserved</a>. Go do something cool with it!
</footer>
</div>);
}
});
module.exports = Article;

17
components/Footer.jsx Normal file
View File

@@ -0,0 +1,17 @@
var React = require('react');
var Footer = React.createClass({
render: function() {
return (
<footer className="copyright">
This article is © 2011-2016 to me, Mike "Pomax" Kamermans, but the text, code,
and images are <a href="https://github.com/Pomax/bezierinfo/blob/gh-pages/LICENSE.md">almost
no rights reserved</a>. Go do something cool with it!
</footer>
);
}
});
module.exports = Footer;

View File

@@ -0,0 +1,19 @@
var React = require("react");
var Page = require("./Page.jsx");
var sectionList = require("./sections"),
sectionMap = function(mapping) {
return Object.keys(sectionList).map(mapping);
},
allSections = sectionMap(function(name, entry) {
var Type = sectionList[name];
return <Type key={name} name={name} number={entry} />;
});
var FullArticle = React.createClass({
render: function() {
return <Page content={ allSections }/>;
}
});
module.exports = FullArticle;

14
components/Header.jsx Normal file
View File

@@ -0,0 +1,14 @@
var React = require('react');
var Header = React.createClass({
render: function() {
return (
<header>
<h1>A Primer on Bézier Curves</h1>
<h2>A free, online book for when you really need to know how to do Bézier things.</h2>
</header>
);
}
});
module.exports = Header;

38
components/Navigation.jsx Normal file
View File

@@ -0,0 +1,38 @@
var React = require('react');
var ReactRouter = require('react-router');
var Link = ReactRouter.Link;
var sections = require("./sections");
var sectionPages = Object.keys(sections);
// LESS is automatically turned into CSS and bundled in:
require("../stylesheets/style.less");
var Navigation = React.createClass({
generateNavItem: function(name, entry) {
var Type = sections[name];
var title = Type.getDefaultProps().title;
var link = <a href={'#' + name}>{ title }</a>;
if (this.props.fullNav) { link = <Link to={(name!=="preface") ? name : "/"}>{title}</Link>; }
return <li key={name} data-number={entry}>{link}</li>;
},
generateNav: function() {
if (this.props.compact) return null;
return (
<div ref="navigation">
<navigation className={ this.props.compact ? "compact" : null }>
<ul className="navigation">
{ sectionPages.map(this.generateNavItem) }
</ul>
</navigation>
</div>
);
},
render: function() {
return this.generateNav();
}
});
module.exports = Navigation;

31
components/Page.jsx Normal file
View File

@@ -0,0 +1,31 @@
var React = require("react");
var Ribbon = require("./Ribbon.jsx");
var Header = require("./Header.jsx");
var Relatives = require("./Relatives.jsx");
var Navigation = require("./Navigation.jsx");
var Footer = require("./Footer.jsx");
var Page = React.createClass({
render: function() {
var nav = <Navigation compact={this.props.compact}/>;
var orderedContent = [nav].concat();
if (this.props.compact) {
orderedContent.splice(0,1);
orderedContent.push(nav);
}
return (
<div>
<Ribbon/>
<Header/>
{nav}
<Relatives prev={this.props.prev} next={this.props.next} position="before" />
{this.props.content}
<Relatives prev={this.props.prev} next={this.props.next} position="after" />
<Footer/>
</div>
);
}
});
module.exports = Page;

46
components/Relatives.jsx Normal file
View File

@@ -0,0 +1,46 @@
var React = require('react');
var ReactRouter = require('react-router');
var Link = ReactRouter.Link;
var sections = require("./sections");
var pageIDs = Object.keys(sections);
var Relatives = React.createClass({
getInitialState() {
console.log(this.props);
var prev = this.props.prev;
if (prev > -1) {
prev = {
to: pageIDs[prev],
title: sections[pageIDs[prev]].getDefaultProps().title
};
} else { prev = false; }
var next = this.props.next;
if (next < pageIDs.length) {
next = {
to: pageIDs[next],
title: sections[pageIDs[next]].getDefaultProps().title
};
} else { next = false; }
return {
prev: prev,
next: next
};
},
render: function() {
if (!this.props.prev && !this.props.next) return null;
return (
<div className={"relatives " + this.props.position}>
{ !this.state.next ? null : <Link className="next" to={this.state.next.to}>{this.props.next + ". " + this.state.next.title}</Link> }
{ this.state.prev ? <Link to="/">Index</Link> : null }
{ !this.state.prev ? null : <Link className="prev" to={this.state.prev.to}>{this.props.prev + ". " + this.state.prev.title}</Link> }
</div>
);
}
});
module.exports = Relatives;

View File

@@ -6,7 +6,8 @@ module.exports = function(Component) {
propName = options.propName || "", propName = options.propName || "",
values = options.values || {}, values = options.values || {},
controller = options.controller || noop, controller = options.controller || noop,
getDefaultProps = Component.getDefaultProps; getDefaultProps = Component.getDefaultProps,
ref = "wrappedComponent";
return React.createClass({ return React.createClass({
values: values, values: values,
@@ -26,8 +27,16 @@ module.exports = function(Component) {
} }
}, },
getComponent: function() {
var wrappedComponent = this.refs[ref];
if (wrappedComponent.getComponent) {
return wrappedComponent.getComponent();
}
return wrappedComponent;
},
render: function() { render: function() {
return <Component {...this.props} onKeyDown={this.onKeyDown} />; return <Component {...this.props} onKeyDown={this.onKeyDown} ref={ref} />;
} }
}); });
}; };

View File

@@ -43,20 +43,20 @@
</div> </div>
<article> <article>
<!-- these rules will get overwritten by the style in the article.js React bundle -->
<style>
header h1, header h2 { text-align: center; }
header h1 { font-size: 300%; margin: 0.2em; }
p.jsnote { margin: 2em; text-align: justify; }
p.jsnote:first-child { width: 13em; margin: auto; }
</style>
<header>
<h1>A Primer on Bézier Curves</h1>
<h2>A free, online book for when you really need to know how to do Bézier things.</h2>
</header>
<div id="article"> <div id="article">
<!-- these rules will get overwritten by the style in the article.js React bundle -->
<style>
header h1, header h2 { text-align: center; }
header h1 { font-size: 300%; margin: 0.2em; }
p.jsnote { margin: 2em; text-align: justify; }
p.jsnote:first-child { width: 13em; margin: auto; }
</style>
<header>
<h1>A Primer on Bézier Curves</h1>
<h2>A free, online book for when you really need to know how to do Bézier things.</h2>
</header>
<!-- This content only shows for as long as JS/React hasn't loaded the page content --> <!-- This content only shows for as long as JS/React hasn't loaded the page content -->
<p class="jsnote">Loading book content<span id="loader">...</span></p> <p class="jsnote">Loading book content<span id="loader">...</span></p>
@@ -66,9 +66,10 @@
</div> </div>
</article> </article>
<script src="article.js" async></script>
<!-- referral tracking, because I like knowing who's linking to my book --> <!-- referral tracking, because I like knowing who's linking to my book -->
<script src="lib/site/referrer.js" async></script> <script src="lib/site/referrer.js" async></script>
<!-- the actual article is a JS bundle -->
<script src="article.js" async></script>
</body> </body>
</html> </html>

2209
lgvalues-abscissa.php Normal file

File diff suppressed because it is too large Load Diff

2209
lgvalues-weights.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,11 @@
"description": "pomax.github.io/bezierinfo", "description": "pomax.github.io/bezierinfo",
"scripts": { "scripts": {
"build": "webpack --prod", "build": "webpack --prod",
"dev": "webpack-dev-server --progress --colors --hot --inline",
"latex": "node tools/mathjax", "latex": "node tools/mathjax",
"start": "webpack-dev-server --progress --colors --hot --inline", "singles": "npm start -- --singles",
"style": "webpack --jscs", "start": "npm run dev",
"test": "npm run lint" "style": "webpack --jscs"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -40,6 +41,7 @@
"eslint-loader": "^1.2.0", "eslint-loader": "^1.2.0",
"eslint-plugin-react": "^3.15.0", "eslint-plugin-react": "^3.15.0",
"file-loader": "^0.8.5", "file-loader": "^0.8.5",
"history": "^1.17.0",
"image-size": "^0.4.0", "image-size": "^0.4.0",
"jsmin": "^1.0.1", "jsmin": "^1.0.1",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
@@ -52,6 +54,7 @@
"react": "^0.14.3", "react": "^0.14.3",
"react-component-visibility": "0.0.8", "react-component-visibility": "0.0.8",
"react-dom": "^0.14.3", "react-dom": "^0.14.3",
"react-router": "^1.0.3",
"sha1": "^1.1.1", "sha1": "^1.1.1",
"style-loader": "^0.13.0", "style-loader": "^0.13.0",
"uglify-loader": "^1.3.0", "uglify-loader": "^1.3.0",

27
pages/Routed.jsx Normal file
View File

@@ -0,0 +1,27 @@
var React = require('react');
var ReactRouter = require('react-router');
var Router = ReactRouter.Router;
var Route = ReactRouter.Route;
var Page = require("../components/Page.jsx");
// get all the sections, and generate <Route> objects for each.
var sections = require("../components/sections");
var generateSingleSection = require("./generateSingleSection");
var pageIDs = Object.keys(sections);
// mind you, "preface" is our root page, so we take it out before generating named routes.
pageIDs.splice(pageIDs.indexOf("preface"), 1);
// Then we generate each page's <Route>
var pages = [
<Route path="/" component={generateSingleSection("preface")} key="preface"/>
].concat(
pageIDs.map(id => <Route path={id} component={generateSingleSection(id)} key={id}/>)
);
// And finally, the full app's route set.
var RouteSet = <Router>{pages}</Router>;
// Done, let's run this thing.
var ReactDOM = require('react-dom');
ReactDOM.render(RouteSet, document.getElementById("article"));

View File

@@ -0,0 +1,23 @@
var React = require('react');
var sections = require('../components/sections');
var Page = require('../components/Page.jsx');
module.exports = function generateSingleSection(name) {
var Type, entry;
Object.keys(sections).map((n,idx) => {
if (name!==n) return;
entry = idx;
Type = sections[name];
});
var section = <Type key={name} name={name} number={entry}/>,
content = [section],
SingleSection = React.createClass({
render: function() {
return <Page content={content} compact={true} prev={entry-1} next={entry+1}/>;
}
});
return SingleSection;
};

View File

@@ -2,6 +2,7 @@ footer {
font-size: 85%; font-size: 85%;
font-family: Verdana; font-family: Verdana;
border-top: 1px solid grey; border-top: 1px solid grey;
padding: 2em 2em 0; padding: 2em 1.25em 0;
box-sizing: border-box; box-sizing: content-box;
margin-left: -1rem;
} }

View File

@@ -19,4 +19,23 @@ navigation {
} }
} }
} }
&.compact {
width: 100%;
border: none;
border-top: 1px solid grey;
padding-top: 2em;
margin-top: 2em;
ul {
background: inherit;
li {
display: inline-block;
&:not(:last-child) {
margin-right: 1em;
}
}
}
}
} }

View File

@@ -0,0 +1,26 @@
.relatives {
width: 100%;
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
border: 1px solid #CCC;
padding: 0.25rem 1rem;
margin-left: -1rem;
box-sizing: content-box;
&.before {
border-width: 1px 0px;
margin-bottom: -2rem;
}
&.after {
margin-top: 2em;
border-width: 1px 0 0 0;
border-color: grey;
margin-bottom: -1.5rem;
}
.prev:before { content: "← "; }
.next:after { content: " →"; }
}

View File

@@ -61,3 +61,4 @@ footer {
@import "latex.less"; @import "latex.less";
@import "table.less"; @import "table.less";
@import "footer.less"; @import "footer.less";
@import "relatives.less";

View File

@@ -3,6 +3,11 @@ var webpack = require('webpack');
// Bundle entry point // Bundle entry point
var entry = ['./components/App.jsx']; var entry = ['./components/App.jsx'];
// However, do we want one full page, or single pages with react-router?
if(process.argv.indexOf("--singles") !== -1 ) {
entry = ['./pages/Routed.jsx'];
}
// Necessary webpack loaders for converting our content: // Necessary webpack loaders for converting our content:
var webpackLoaders = [ var webpackLoaders = [
'babel-loader', 'babel-loader',
@@ -41,7 +46,7 @@ module.exports = {
{ test: /\.json$/, loader: "json" }, { test: /\.json$/, loader: "json" },
{ {
test: /.jsx?$/, test: /.jsx?$/,
include: /components/, include: /(components|pages)/,
loaders: webpackLoaders loaders: webpackLoaders
} }
] ]