mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
ESLintify Part 1 (#837)
* ESLint-ify * Allow empty try/catch * Escape regexp
This commit is contained in:
parent
128dbfca0a
commit
e8e3f42685
44 changed files with 466 additions and 555 deletions
42
.eslintrc.js
42
.eslintrc.js
|
@ -16,53 +16,23 @@ module.exports = {
|
||||||
'no-console': OFF,
|
'no-console': OFF,
|
||||||
// require radix argument in parseInt
|
// require radix argument in parseInt
|
||||||
radix: ERROR,
|
radix: ERROR,
|
||||||
|
'class-methods-use-this': OFF,
|
||||||
|
'react/no-multi-comp': OFF,
|
||||||
|
'import/no-extraneous-dependencies': OFF,
|
||||||
|
'react/no-danger': OFF,
|
||||||
|
'no-empty': [ERROR, {allowEmptyCatch: true}],
|
||||||
|
|
||||||
// Existing ESLint errors sorted by frequency, silencing first.
|
// Existing ESLint errors sorted by frequency, silencing first.
|
||||||
'react/button-has-type': OFF, // 1
|
'react/button-has-type': OFF, // 1
|
||||||
null: OFF, // 1
|
|
||||||
'react/no-unused-state': OFF, // 1
|
|
||||||
'vars-on-top': OFF, // 1
|
|
||||||
'react/forbid-prop-types': OFF, // 1
|
'react/forbid-prop-types': OFF, // 1
|
||||||
'react/require-default-props': OFF, // 1
|
'react/require-default-props': OFF, // 1
|
||||||
'lines-between-class-members': OFF, // 1
|
|
||||||
strict: OFF, // 1
|
|
||||||
'no-restricted-syntax': OFF, // 1
|
|
||||||
'no-path-concat': OFF, // 2
|
|
||||||
'one-var': OFF, // 2
|
|
||||||
'no-unused-expressions': OFF, // 2
|
|
||||||
'react/jsx-boolean-value': OFF, // 2
|
|
||||||
'jsx-a11y/html-has-lang': OFF, // 2
|
|
||||||
'no-var': OFF, // 2
|
|
||||||
'no-useless-return': OFF, // 2
|
|
||||||
'jsx-a11y/anchor-has-content': OFF, // 2
|
|
||||||
'react/jsx-no-comment-textnodes': OFF, // 3
|
|
||||||
'no-continue': OFF, // 3
|
|
||||||
'jsx-a11y/alt-text': OFF, // 3
|
|
||||||
'react/jsx-tag-spacing': OFF, // 3
|
|
||||||
'no-lonely-if': OFF, // 3
|
|
||||||
'react/sort-comp': OFF, // 4
|
|
||||||
'no-cond-assign': OFF, // 4
|
|
||||||
'no-use-before-define': OFF, // 4
|
|
||||||
'no-empty': OFF, // 4
|
|
||||||
'no-shadow': OFF, // 4
|
|
||||||
'class-methods-use-this': OFF, // 5
|
|
||||||
eqeqeq: OFF, // 5
|
|
||||||
'react/no-multi-comp': OFF, // 5
|
|
||||||
'react/no-array-index-key': OFF, // 6
|
|
||||||
'no-underscore-dangle': OFF, // 6
|
|
||||||
'array-callback-return': OFF, // 6
|
|
||||||
'import/no-extraneous-dependencies': OFF, // 7
|
|
||||||
'no-else-return': OFF, // 9
|
|
||||||
'jsx-a11y/anchor-is-valid': OFF, // 9
|
'jsx-a11y/anchor-is-valid': OFF, // 9
|
||||||
'import/order': OFF, // 10
|
|
||||||
'arrow-body-style': OFF, // 10
|
'arrow-body-style': OFF, // 10
|
||||||
camelcase: OFF, // 10
|
|
||||||
'react/jsx-curly-brace-presence': OFF, // 11
|
'react/jsx-curly-brace-presence': OFF, // 11
|
||||||
'react/no-unescaped-entities': OFF, // 12
|
'react/no-unescaped-entities': OFF, // 12
|
||||||
'no-param-reassign': OFF, // 12
|
'no-param-reassign': OFF, // 12
|
||||||
'no-unused-vars': OFF, // 13
|
|
||||||
'spaced-comment': OFF, // 14
|
'spaced-comment': OFF, // 14
|
||||||
'import/no-unresolved': OFF, // 15
|
'import/no-unresolved': OFF, // 15
|
||||||
'react/no-danger': OFF, // 16
|
|
||||||
'object-shorthand': OFF, // 16
|
'object-shorthand': OFF, // 16
|
||||||
'dot-notation': OFF, // 19
|
'dot-notation': OFF, // 19
|
||||||
'react/prefer-stateless-function': OFF, // 22
|
'react/prefer-stateless-function': OFF, // 22
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Footer extends React.Component {
|
||||||
href={this.props.config.repoUrl}
|
href={this.props.config.repoUrl}
|
||||||
data-icon="octicon-star"
|
data-icon="octicon-star"
|
||||||
data-count-href="/facebook/docusaurus/stargazers"
|
data-count-href="/facebook/docusaurus/stargazers"
|
||||||
data-show-count={true}
|
data-show-count="true"
|
||||||
data-count-aria-label="# stargazers on GitHub"
|
data-count-aria-label="# stargazers on GitHub"
|
||||||
aria-label="Star this project on GitHub">
|
aria-label="Star this project on GitHub">
|
||||||
Star
|
Star
|
||||||
|
|
|
@ -52,11 +52,11 @@ const SplashContainer = props => (
|
||||||
|
|
||||||
const Logo = props => (
|
const Logo = props => (
|
||||||
<div className="projectLogo">
|
<div className="projectLogo">
|
||||||
<img src={props.img_src} />
|
<img src={props.img_src} alt="Project Logo" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const ProjectTitle = props => (
|
const ProjectTitle = () => (
|
||||||
<h2 className="projectTitle">
|
<h2 className="projectTitle">
|
||||||
{siteConfig.title}
|
{siteConfig.title}
|
||||||
<small>{siteConfig.tagline}</small>
|
<small>{siteConfig.tagline}</small>
|
||||||
|
@ -99,7 +99,7 @@ const Block = props => (
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Features = props => (
|
const Features = () => (
|
||||||
<Block layout="fourColumn">
|
<Block layout="fourColumn">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
@ -118,7 +118,7 @@ const Features = props => (
|
||||||
</Block>
|
</Block>
|
||||||
);
|
);
|
||||||
|
|
||||||
const FeatureCallout = props => (
|
const FeatureCallout = () => (
|
||||||
<div
|
<div
|
||||||
className="productShowcaseSection paddingBottom"
|
className="productShowcaseSection paddingBottom"
|
||||||
style={{textAlign: 'center'}}>
|
style={{textAlign: 'center'}}>
|
||||||
|
@ -127,7 +127,7 @@ const FeatureCallout = props => (
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const LearnHow = props => (
|
const LearnHow = () => (
|
||||||
<Block background="light">
|
<Block background="light">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
@ -140,7 +140,7 @@ const LearnHow = props => (
|
||||||
</Block>
|
</Block>
|
||||||
);
|
);
|
||||||
|
|
||||||
const TryOut = props => (
|
const TryOut = () => (
|
||||||
<Block id="try">
|
<Block id="try">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
@ -153,7 +153,7 @@ const TryOut = props => (
|
||||||
</Block>
|
</Block>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Description = props => (
|
const Description = () => (
|
||||||
<Block background="dark">
|
<Block background="dark">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
@ -170,21 +170,16 @@ const Showcase = props => {
|
||||||
if ((siteConfig.users || []).length === 0) {
|
if ((siteConfig.users || []).length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const showcase = siteConfig.users
|
|
||||||
.filter(user => {
|
const showcase = siteConfig.users.filter(user => user.pinned).map(user => (
|
||||||
return user.pinned;
|
<a href={user.infoLink} key={user.infoLink}>
|
||||||
})
|
|
||||||
.map((user, i) => {
|
|
||||||
return (
|
|
||||||
<a href={user.infoLink} key={i}>
|
|
||||||
<img src={user.image} alt={user.caption} title={user.caption} />
|
<img src={user.image} alt={user.caption} title={user.caption} />
|
||||||
</a>
|
</a>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="productShowcaseSection paddingBottom">
|
<div className="productShowcaseSection paddingBottom">
|
||||||
<h2>{"Who's Using This?"}</h2>
|
<h2>Who's Using This?</h2>
|
||||||
<p>This project is used by all these people</p>
|
<p>This project is used by all these people</p>
|
||||||
<div className="logos">{showcase}</div>
|
<div className="logos">{showcase}</div>
|
||||||
<div className="more-users">
|
<div className="more-users">
|
||||||
|
|
|
@ -17,14 +17,13 @@ class Users extends React.Component {
|
||||||
if ((siteConfig.users || []).length === 0) {
|
if ((siteConfig.users || []).length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const editUrl = siteConfig.repoUrl + '/edit/master/website/siteConfig.js';
|
const editUrl = siteConfig.repoUrl + '/edit/master/website/siteConfig.js';
|
||||||
const showcase = siteConfig.users.map((user, i) => {
|
const showcase = siteConfig.users.map(user => (
|
||||||
return (
|
<a href={user.infoLink} key={user.infoLink}>
|
||||||
<a href={user.infoLink} key={i}>
|
|
||||||
<img src={user.image} alt={user.caption} title={user.caption} />
|
<img src={user.image} alt={user.caption} title={user.caption} />
|
||||||
</a>
|
</a>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mainContainer">
|
<div className="mainContainer">
|
||||||
|
|
|
@ -52,7 +52,6 @@ beforeAll(() => {
|
||||||
inputAssetsFiles,
|
inputAssetsFiles,
|
||||||
outputAssetsFiles,
|
outputAssetsFiles,
|
||||||
] = results;
|
] = results;
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const React = require('react');
|
||||||
const BlogPost = require('./BlogPost.js');
|
const BlogPost = require('./BlogPost.js');
|
||||||
const BlogSidebar = require('./BlogSidebar.js');
|
const BlogSidebar = require('./BlogSidebar.js');
|
||||||
const Container = require('./Container.js');
|
const Container = require('./Container.js');
|
||||||
const MetadataBlog = require('./MetadataBlog.js');
|
const MetadataBlog = require('./MetadataBlog.js');
|
||||||
const React = require('react');
|
|
||||||
const Site = require('./Site.js');
|
const Site = require('./Site.js');
|
||||||
const utils = require('./utils.js');
|
const utils = require('./utils.js');
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class BlogPageLayout extends React.Component {
|
||||||
<BlogPost
|
<BlogPost
|
||||||
post={post}
|
post={post}
|
||||||
content={post.content}
|
content={post.content}
|
||||||
truncate={true}
|
truncate
|
||||||
key={
|
key={
|
||||||
utils.getPath(post.path, this.props.config.cleanUrl) +
|
utils.getPath(post.path, this.props.config.cleanUrl) +
|
||||||
post.title
|
post.title
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const MarkdownBlock = require('./MarkdownBlock.js');
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
|
const MarkdownBlock = require('./MarkdownBlock.js');
|
||||||
const utils = require('./utils.js');
|
const utils = require('./utils.js');
|
||||||
|
|
||||||
// inner blog component for the article itself, without sidebar/header/footer
|
// inner blog component for the article itself, without sidebar/header/footer
|
||||||
|
@ -46,33 +46,22 @@ class BlogPost extends React.Component {
|
||||||
const className =
|
const className =
|
||||||
'authorPhoto' +
|
'authorPhoto' +
|
||||||
(post.author && post.authorTitle ? ' authorPhotoBig' : '');
|
(post.author && post.authorTitle ? ' authorPhotoBig' : '');
|
||||||
if (post.authorFBID) {
|
if (post.authorFBID || post.authorImageURL) {
|
||||||
|
const authorImageURL = post.authorFBID
|
||||||
|
? `https://graph.facebook.com/${
|
||||||
|
post.authorFBID
|
||||||
|
}/picture/?height=200&width=200`
|
||||||
|
: post.authorImageURL;
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
<a href={post.authorURL} target="_blank" rel="noreferrer noopener">
|
<a href={post.authorURL} target="_blank" rel="noreferrer noopener">
|
||||||
<img
|
<img src={authorImageURL} alt={post.author} />
|
||||||
src={
|
</a>
|
||||||
'https://graph.facebook.com/' +
|
</div>
|
||||||
post.authorFBID +
|
);
|
||||||
'/picture/?height=200&width=200'
|
|
||||||
}
|
}
|
||||||
alt={post.author}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else if (post.authorImageURL) {
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
<a href={post.authorURL} target="_blank" rel="noreferrer noopener">
|
|
||||||
<img src={post.authorImageURL} />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
renderTitle() {
|
renderTitle() {
|
||||||
const post = this.props.post;
|
const post = this.props.post;
|
||||||
|
|
|
@ -5,19 +5,31 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const classNames = require('classnames');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
const BlogPost = require('./BlogPost.js');
|
const BlogPost = require('./BlogPost.js');
|
||||||
const BlogSidebar = require('./BlogSidebar.js');
|
const BlogSidebar = require('./BlogSidebar.js');
|
||||||
const Container = require('./Container.js');
|
const Container = require('./Container.js');
|
||||||
const Site = require('./Site.js');
|
const Site = require('./Site.js');
|
||||||
const OnPageNav = require('./nav/OnPageNav.js');
|
const OnPageNav = require('./nav/OnPageNav.js');
|
||||||
const utils = require('./utils.js');
|
const utils = require('./utils.js');
|
||||||
const classNames = require('classnames');
|
|
||||||
|
|
||||||
// used for entire blog posts, i.e., each written blog article with sidebar with site header/footer
|
// used for entire blog posts, i.e., each written blog article with sidebar with site header/footer
|
||||||
class BlogPostLayout extends React.Component {
|
class BlogPostLayout extends React.Component {
|
||||||
|
getDescription() {
|
||||||
|
const descLines = this.props.children.trim().split('\n');
|
||||||
|
for (let i = 0; i < descLines.length; i++) {
|
||||||
|
// Don't want blank lines or descriptions that are raw image rendering strings.
|
||||||
|
if (descLines[i] && !descLines[i].startsWith('![')) {
|
||||||
|
return descLines[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
renderSocialButtons() {
|
renderSocialButtons() {
|
||||||
let post = this.props.metadata;
|
const post = this.props.metadata;
|
||||||
post.path = utils.getPath(post.path, this.props.config.cleanUrl);
|
post.path = utils.getPath(post.path, this.props.config.cleanUrl);
|
||||||
|
|
||||||
const fbComment = this.props.config.facebookAppId &&
|
const fbComment = this.props.config.facebookAppId &&
|
||||||
|
@ -72,8 +84,9 @@ class BlogPostLayout extends React.Component {
|
||||||
}
|
}
|
||||||
data-related={this.props.config.twitter}
|
data-related={this.props.config.twitter}
|
||||||
data-via={post.authorTwitter}
|
data-via={post.authorTwitter}
|
||||||
data-show-count="false"
|
data-show-count="false">
|
||||||
/>
|
Tweet
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -86,17 +99,6 @@ class BlogPostLayout extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDescription() {
|
|
||||||
const descLines = this.props.children.trim().split('\n');
|
|
||||||
for (var i = 0; i < descLines.length; i++) {
|
|
||||||
// Don't want blank lines or descriptions that are raw image rendering strings
|
|
||||||
if (descLines[i] && !descLines[i].startsWith('![')) {
|
|
||||||
return descLines[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const hasOnPageNav = this.props.config.onPageNav === 'separate';
|
const hasOnPageNav = this.props.config.onPageNav === 'separate';
|
||||||
const post = this.props.metadata;
|
const post = this.props.metadata;
|
||||||
|
|
|
@ -17,7 +17,7 @@ class BlogSidebar extends React.Component {
|
||||||
let blogSidebarTitleConfig = this.props.config.blogSidebarTitle || {};
|
let blogSidebarTitleConfig = this.props.config.blogSidebarTitle || {};
|
||||||
let blogSidebarTitle = blogSidebarTitleConfig.default || 'Recent Posts';
|
let blogSidebarTitle = blogSidebarTitleConfig.default || 'Recent Posts';
|
||||||
if (this.props.config.blogSidebarCount) {
|
if (this.props.config.blogSidebarCount) {
|
||||||
if (this.props.config.blogSidebarCount == 'ALL') {
|
if (this.props.config.blogSidebarCount === 'ALL') {
|
||||||
blogSidebarCount = MetadataBlog.length;
|
blogSidebarCount = MetadataBlog.length;
|
||||||
blogSidebarTitle = blogSidebarTitleConfig.all || 'All Blog Posts';
|
blogSidebarTitle = blogSidebarTitleConfig.all || 'All Blog Posts';
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Doc extends React.Component {
|
||||||
// If internationalization is enabled, show Recruiting link instead of Edit Link.
|
// If internationalization is enabled, show Recruiting link instead of Edit Link.
|
||||||
if (
|
if (
|
||||||
this.props.language &&
|
this.props.language &&
|
||||||
this.props.language != 'en' &&
|
this.props.language !== 'en' &&
|
||||||
this.props.config.translationRecruitingLink
|
this.props.config.translationRecruitingLink
|
||||||
) {
|
) {
|
||||||
editLink = (
|
editLink = (
|
||||||
|
|
|
@ -5,16 +5,17 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const classNames = require('classnames');
|
||||||
|
const path = require('path');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
const url = require('url');
|
||||||
|
|
||||||
const Container = require('./Container.js');
|
const Container = require('./Container.js');
|
||||||
const Doc = require('./Doc.js');
|
const Doc = require('./Doc.js');
|
||||||
const DocsSidebar = require('./DocsSidebar.js');
|
const DocsSidebar = require('./DocsSidebar.js');
|
||||||
const OnPageNav = require('./nav/OnPageNav.js');
|
const OnPageNav = require('./nav/OnPageNav.js');
|
||||||
const Site = require('./Site.js');
|
const Site = require('./Site.js');
|
||||||
const translation = require('../server/translation.js');
|
const translation = require('../server/translation.js');
|
||||||
const classNames = require('classnames');
|
|
||||||
const path = require('path');
|
|
||||||
const url = require('url');
|
|
||||||
|
|
||||||
// component used to generate whole webpage for docs, including sidebar/header/footer
|
// component used to generate whole webpage for docs, including sidebar/header/footer
|
||||||
class DocsLayout extends React.Component {
|
class DocsLayout extends React.Component {
|
||||||
|
|
|
@ -48,37 +48,33 @@ class GridBlock extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBlockImage(image, imageLink, imageAlt) {
|
renderBlockImage(image, imageLink, imageAlt) {
|
||||||
if (image) {
|
if (!image) {
|
||||||
if (imageLink) {
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="blockImage">
|
<div className="blockImage">
|
||||||
|
{imageLink ? (
|
||||||
<a href={imageLink}>
|
<a href={imageLink}>
|
||||||
<img src={image} alt={imageAlt} />
|
<img src={image} alt={imageAlt} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
) : (
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<div className="blockImage">
|
|
||||||
<img src={image} alt={imageAlt} />
|
<img src={image} alt={imageAlt} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBlockTitle(title) {
|
renderBlockTitle(title) {
|
||||||
if (title) {
|
if (!title) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<h2>
|
<h2>
|
||||||
<MarkdownBlock>{title}</MarkdownBlock>
|
<MarkdownBlock>{title}</MarkdownBlock>
|
||||||
</h2>
|
</h2>
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -11,10 +11,7 @@ const React = require('react');
|
||||||
class Head extends React.Component {
|
class Head extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const links = this.props.config.headerLinks;
|
const links = this.props.config.headerLinks;
|
||||||
let hasBlog = false;
|
const hasBlog = links.some(link => link.blog);
|
||||||
links.map(link => {
|
|
||||||
if (link.blog) hasBlog = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
let highlight = {
|
let highlight = {
|
||||||
version: '9.12.0',
|
version: '9.12.0',
|
||||||
|
@ -137,21 +134,13 @@ class Head extends React.Component {
|
||||||
|
|
||||||
{/* External resources */}
|
{/* External resources */}
|
||||||
{this.props.config.stylesheets &&
|
{this.props.config.stylesheets &&
|
||||||
this.props.config.stylesheets.map(function(source, idx) {
|
this.props.config.stylesheets.map(source => (
|
||||||
return (
|
<link rel="stylesheet" key={source} href={source} />
|
||||||
<link rel="stylesheet" key={'stylesheet' + idx} href={source} />
|
))}
|
||||||
);
|
|
||||||
})}
|
|
||||||
{this.props.config.scripts &&
|
{this.props.config.scripts &&
|
||||||
this.props.config.scripts.map(function(source, idx) {
|
this.props.config.scripts.map(source => (
|
||||||
return (
|
<script type="text/javascript" key={source} src={source} />
|
||||||
<script
|
))}
|
||||||
type="text/javascript"
|
|
||||||
key={'script' + idx}
|
|
||||||
src={source}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
{this.props.config.scrollToTop && (
|
{this.props.config.scrollToTop && (
|
||||||
<script
|
<script
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2017-present, Facebook, Inc.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const React = require('react');
|
|
||||||
const toSlug = require('./toSlug.js');
|
|
||||||
|
|
||||||
class Header extends React.Component {
|
|
||||||
render() {
|
|
||||||
const slug = toSlug(this.props.toSlug || this.props.children);
|
|
||||||
const Heading = 'h' + this.props.level;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Heading {...this.props}>
|
|
||||||
<a className="anchor" id={slug} />
|
|
||||||
{this.props.children}{' '}
|
|
||||||
<a className="hash-link" href={'#' + slug}>
|
|
||||||
#
|
|
||||||
</a>
|
|
||||||
</Heading>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Header;
|
|
|
@ -29,7 +29,7 @@ class Redirect extends React.Component {
|
||||||
const redirect = this.props.redirect || false;
|
const redirect = this.props.redirect || false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html>
|
<html lang="en">
|
||||||
<Head
|
<Head
|
||||||
config={this.props.config}
|
config={this.props.config}
|
||||||
description={description}
|
description={description}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const renderMarkdown = require('./renderMarkdown.js');
|
const renderMarkdown = require('./renderMarkdown.js');
|
||||||
|
|
||||||
|
@ -20,22 +18,21 @@ class Remarkable extends React.Component {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
return React.Children.map(this.props.children, child => {
|
return React.Children.map(this.props.children, child => {
|
||||||
if (typeof child === 'string') {
|
if (typeof child === 'string') {
|
||||||
return (
|
return (
|
||||||
<span dangerouslySetInnerHTML={{__html: renderMarkdown(child)}} />
|
<span dangerouslySetInnerHTML={{__html: renderMarkdown(child)}} />
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
return child;
|
return child;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var Container = this.props.container;
|
const Container = this.props.container;
|
||||||
|
|
||||||
return <Container>{this.content()}</Container>;
|
return <Container>{this.content()}</Container>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,14 +39,8 @@ class Site extends React.Component {
|
||||||
docsVersion = latestVersion;
|
docsVersion = latestVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not want a lang attribute for the html tag if we don't have a language set
|
|
||||||
const htmlElementProps = {};
|
|
||||||
if (this.props.language) {
|
|
||||||
htmlElementProps.lang = this.props.language;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html {...htmlElementProps}>
|
<html lang={this.props.language}>
|
||||||
<Head
|
<Head
|
||||||
config={this.props.config}
|
config={this.props.config}
|
||||||
description={description}
|
description={description}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const anchors = require('../anchors');
|
|
||||||
const rules = require('remarkable/lib/rules');
|
const rules = require('remarkable/lib/rules');
|
||||||
|
const anchors = require('../anchors');
|
||||||
|
|
||||||
const md = {
|
const md = {
|
||||||
renderer: {
|
renderer: {
|
||||||
|
|
|
@ -11,7 +11,7 @@ const getTOC = require('../getTOC');
|
||||||
|
|
||||||
const mdContents = readFileSync(
|
const mdContents = readFileSync(
|
||||||
path.join(__dirname, '__fixtures__', 'getTOC.md'),
|
path.join(__dirname, '__fixtures__', 'getTOC.md'),
|
||||||
'utf-8'
|
'utf8'
|
||||||
);
|
);
|
||||||
|
|
||||||
test('with defaults', () => {
|
test('with defaults', () => {
|
||||||
|
|
|
@ -6,17 +6,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const readFileSync = require('fs').readFileSync;
|
|
||||||
|
|
||||||
const blogPostWithTruncateContents = readFileSync(
|
const blogPostWithTruncateContents = fs.readFileSync(
|
||||||
path.join(__dirname, '__fixtures__', 'blog-post-with-truncate.md'),
|
path.join(__dirname, '__fixtures__', 'blog-post-with-truncate.md'),
|
||||||
'utf-8'
|
'utf8'
|
||||||
);
|
);
|
||||||
|
|
||||||
const blogPostWithoutTruncateContents = readFileSync(
|
const blogPostWithoutTruncateContents = fs.readFileSync(
|
||||||
path.join(__dirname, '__fixtures__', 'blog-post-without-truncate.md'),
|
path.join(__dirname, '__fixtures__', 'blog-post-without-truncate.md'),
|
||||||
'utf-8'
|
'utf8'
|
||||||
);
|
);
|
||||||
|
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
|
|
|
@ -52,8 +52,8 @@ module.exports = (content, headingTags = 'h2', subHeadingTags = 'h3') => {
|
||||||
if (headingLevels.includes(heading.lvl)) {
|
if (headingLevels.includes(heading.lvl)) {
|
||||||
toc.push(entry);
|
toc.push(entry);
|
||||||
current = entry;
|
current = entry;
|
||||||
} else {
|
} else if (current) {
|
||||||
current && current.children.push(entry);
|
current.children.push(entry);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ class LanguageDropDown extends React.Component {
|
||||||
<img
|
<img
|
||||||
className="languages-icon"
|
className="languages-icon"
|
||||||
src={this.props.baseUrl + 'img/language.svg'}
|
src={this.props.baseUrl + 'img/language.svg'}
|
||||||
|
alt="Languages icon"
|
||||||
/>
|
/>
|
||||||
{currentLanguage}
|
{currentLanguage}
|
||||||
</a>
|
</a>
|
||||||
|
@ -120,12 +121,6 @@ class LanguageDropDown extends React.Component {
|
||||||
|
|
||||||
// header navbar used by all pages generated with docusaurus
|
// header navbar used by all pages generated with docusaurus
|
||||||
class HeaderNav extends React.Component {
|
class HeaderNav extends React.Component {
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
slideoutActive: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// function to generate each header link, used with each object in siteConfig.headerLinks
|
// function to generate each header link, used with each object in siteConfig.headerLinks
|
||||||
makeLinks(link) {
|
makeLinks(link) {
|
||||||
let href;
|
let href;
|
||||||
|
@ -143,7 +138,8 @@ class HeaderNav extends React.Component {
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
} else if (link.languages) {
|
}
|
||||||
|
if (link.languages) {
|
||||||
if (
|
if (
|
||||||
env.translation.enabled &&
|
env.translation.enabled &&
|
||||||
env.translation.enabledLanguages().length > 1
|
env.translation.enabledLanguages().length > 1
|
||||||
|
@ -157,10 +153,10 @@ class HeaderNav extends React.Component {
|
||||||
key="languagedropdown"
|
key="languagedropdown"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else if (link.doc) {
|
if (link.doc) {
|
||||||
// set link to document with current page's language/version
|
// set link to document with current page's language/version
|
||||||
const langPart = env.translation.enabled
|
const langPart = env.translation.enabled
|
||||||
? (this.props.language || 'en') + '-'
|
? (this.props.language || 'en') + '-'
|
||||||
|
@ -238,47 +234,6 @@ class HeaderNav extends React.Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
const headerClass = siteConfig.headerIcon
|
|
||||||
? 'headerTitleWithLogo'
|
|
||||||
: 'headerTitle';
|
|
||||||
const versionsLink =
|
|
||||||
this.props.baseUrl +
|
|
||||||
(env.translation.enabled
|
|
||||||
? this.props.language + '/versions' + extension
|
|
||||||
: 'versions' + extension);
|
|
||||||
return (
|
|
||||||
<div className="fixedHeaderContainer">
|
|
||||||
<div className="headerWrapper wrapper">
|
|
||||||
<header>
|
|
||||||
<a
|
|
||||||
href={
|
|
||||||
this.props.baseUrl +
|
|
||||||
(env.translation.enabled ? this.props.language : '')
|
|
||||||
}>
|
|
||||||
{siteConfig.headerIcon && (
|
|
||||||
<img
|
|
||||||
className="logo"
|
|
||||||
src={this.props.baseUrl + siteConfig.headerIcon}
|
|
||||||
alt={siteConfig.title}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!this.props.config.disableHeaderTitle && (
|
|
||||||
<h2 className={headerClass}>{this.props.title}</h2>
|
|
||||||
)}
|
|
||||||
</a>
|
|
||||||
{env.versioning.enabled && (
|
|
||||||
<a href={versionsLink}>
|
|
||||||
<h3>{this.props.version || env.versioning.defaultVersion}</h3>
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
{this.renderResponsiveNav()}
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderResponsiveNav() {
|
renderResponsiveNav() {
|
||||||
const headerLinks = this.props.config.headerLinks;
|
const headerLinks = this.props.config.headerLinks;
|
||||||
// add language drop down to end if location not specified
|
// add language drop down to end if location not specified
|
||||||
|
@ -336,6 +291,47 @@ class HeaderNav extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const headerClass = siteConfig.headerIcon
|
||||||
|
? 'headerTitleWithLogo'
|
||||||
|
: 'headerTitle';
|
||||||
|
const versionsLink =
|
||||||
|
this.props.baseUrl +
|
||||||
|
(env.translation.enabled
|
||||||
|
? this.props.language + '/versions' + extension
|
||||||
|
: 'versions' + extension);
|
||||||
|
return (
|
||||||
|
<div className="fixedHeaderContainer">
|
||||||
|
<div className="headerWrapper wrapper">
|
||||||
|
<header>
|
||||||
|
<a
|
||||||
|
href={
|
||||||
|
this.props.baseUrl +
|
||||||
|
(env.translation.enabled ? this.props.language : '')
|
||||||
|
}>
|
||||||
|
{siteConfig.headerIcon && (
|
||||||
|
<img
|
||||||
|
className="logo"
|
||||||
|
src={this.props.baseUrl + siteConfig.headerIcon}
|
||||||
|
alt={siteConfig.title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!this.props.config.disableHeaderTitle && (
|
||||||
|
<h2 className={headerClass}>{this.props.title}</h2>
|
||||||
|
)}
|
||||||
|
</a>
|
||||||
|
{env.versioning.enabled && (
|
||||||
|
<a href={versionsLink}>
|
||||||
|
<h3>{this.props.version || env.versioning.defaultVersion}</h3>
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
{this.renderResponsiveNav()}
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderNav.defaultProps = {
|
HeaderNav.defaultProps = {
|
||||||
|
|
|
@ -23,8 +23,8 @@ const Headings = ({headings}) => {
|
||||||
if (!headings.length) return null;
|
if (!headings.length) return null;
|
||||||
return (
|
return (
|
||||||
<ul className="toc-headings">
|
<ul className="toc-headings">
|
||||||
{headings.map((heading, i) => (
|
{headings.map(heading => (
|
||||||
<li key={i}>
|
<li key={heading.hashLink}>
|
||||||
<Link hashLink={heading.hashLink} content={heading.content} />
|
<Link hashLink={heading.hashLink} content={heading.content} />
|
||||||
<Headings headings={heading.children} />
|
<Headings headings={heading.children} />
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -13,6 +13,77 @@ const translation = require('../../server/translation.js');
|
||||||
const utils = require('../utils.js');
|
const utils = require('../utils.js');
|
||||||
|
|
||||||
class SideNav extends React.Component {
|
class SideNav extends React.Component {
|
||||||
|
// return appropriately translated category string
|
||||||
|
getLocalizedCategoryString(category) {
|
||||||
|
let categoryString = translation[this.props.language]
|
||||||
|
? translation[this.props.language]['localized-strings'][category] ||
|
||||||
|
category
|
||||||
|
: category;
|
||||||
|
return categoryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return appropriately translated label to use for doc/blog in sidebar
|
||||||
|
getLocalizedString(metadata) {
|
||||||
|
let localizedString;
|
||||||
|
const i18n = translation[this.props.language];
|
||||||
|
const sbTitle = metadata.sidebar_label;
|
||||||
|
|
||||||
|
if (sbTitle) {
|
||||||
|
localizedString = i18n
|
||||||
|
? i18n['localized-strings'][sbTitle] || sbTitle
|
||||||
|
: sbTitle;
|
||||||
|
} else {
|
||||||
|
const id = metadata.original_id || metadata.localized_id;
|
||||||
|
localizedString = i18n
|
||||||
|
? i18n['localized-strings'][id] || metadata.title
|
||||||
|
: metadata.title;
|
||||||
|
}
|
||||||
|
return localizedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return link to doc in sidebar
|
||||||
|
getLink(metadata) {
|
||||||
|
if (metadata.permalink) {
|
||||||
|
const targetLink = utils.getPath(metadata.permalink, siteConfig.cleanUrl);
|
||||||
|
if (targetLink.match(/^https?:/)) {
|
||||||
|
return targetLink;
|
||||||
|
}
|
||||||
|
return siteConfig.baseUrl + targetLink;
|
||||||
|
}
|
||||||
|
if (metadata.path) {
|
||||||
|
return (
|
||||||
|
siteConfig.baseUrl +
|
||||||
|
'blog/' +
|
||||||
|
utils.getPath(metadata.path, siteConfig.cleanUrl)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCategory(category) {
|
||||||
|
return (
|
||||||
|
<div className="navGroup" key={category.name}>
|
||||||
|
<h3 className="navGroupCategoryTitle">
|
||||||
|
{this.getLocalizedCategoryString(category.name)}
|
||||||
|
</h3>
|
||||||
|
<ul>{category.links.map(this.renderItemLink, this)}</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItemLink(link) {
|
||||||
|
const itemClasses = classNames('navListItem', {
|
||||||
|
navListItemActive: link.id === this.props.current.id,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<li className={itemClasses} key={link.id}>
|
||||||
|
<a className="navItem" href={this.getLink(link)}>
|
||||||
|
{this.getLocalizedString(link)}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<nav className="toc">
|
<nav className="toc">
|
||||||
|
@ -70,77 +141,6 @@ class SideNav extends React.Component {
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCategory(category) {
|
|
||||||
return (
|
|
||||||
<div className="navGroup" key={category.name}>
|
|
||||||
<h3 className="navGroupCategoryTitle">
|
|
||||||
{this.getLocalizedCategoryString(category.name)}
|
|
||||||
</h3>
|
|
||||||
<ul>{category.links.map(this.renderItemLink, this)}</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return appropriately translated category string
|
|
||||||
getLocalizedCategoryString(category) {
|
|
||||||
let categoryString = translation[this.props.language]
|
|
||||||
? translation[this.props.language]['localized-strings'][category] ||
|
|
||||||
category
|
|
||||||
: category;
|
|
||||||
return categoryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return appropriately translated label to use for doc/blog in sidebar
|
|
||||||
getLocalizedString(metadata) {
|
|
||||||
let localizedString;
|
|
||||||
const i18n = translation[this.props.language];
|
|
||||||
const sbTitle = metadata.sidebar_label;
|
|
||||||
|
|
||||||
if (sbTitle) {
|
|
||||||
localizedString = i18n
|
|
||||||
? i18n['localized-strings'][sbTitle] || sbTitle
|
|
||||||
: sbTitle;
|
|
||||||
} else {
|
|
||||||
const id = metadata.original_id || metadata.localized_id;
|
|
||||||
localizedString = i18n
|
|
||||||
? i18n['localized-strings'][id] || metadata.title
|
|
||||||
: metadata.title;
|
|
||||||
}
|
|
||||||
return localizedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return link to doc in sidebar
|
|
||||||
getLink(metadata) {
|
|
||||||
if (metadata.permalink) {
|
|
||||||
const targetLink = utils.getPath(metadata.permalink, siteConfig.cleanUrl);
|
|
||||||
if (targetLink.match(/^https?:/)) {
|
|
||||||
return targetLink;
|
|
||||||
}
|
|
||||||
return siteConfig.baseUrl + targetLink;
|
|
||||||
}
|
|
||||||
if (metadata.path) {
|
|
||||||
return (
|
|
||||||
siteConfig.baseUrl +
|
|
||||||
'blog/' +
|
|
||||||
utils.getPath(metadata.path, siteConfig.cleanUrl)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderItemLink(link) {
|
|
||||||
const itemClasses = classNames('navListItem', {
|
|
||||||
navListItemActive: link.id === this.props.current.id,
|
|
||||||
});
|
|
||||||
return (
|
|
||||||
<li className={itemClasses} key={link.id}>
|
|
||||||
<a className="navItem" href={this.getLink(link)}>
|
|
||||||
{this.getLocalizedString(link)}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SideNav.defaultProps = {
|
SideNav.defaultProps = {
|
||||||
|
|
|
@ -42,17 +42,23 @@ class MarkdownRenderer {
|
||||||
// every single language (https://github.com/PrismJS/prism/issues/593)
|
// every single language (https://github.com/PrismJS/prism/issues/593)
|
||||||
require('prismjs/components/prism-' + language + '.min');
|
require('prismjs/components/prism-' + language + '.min');
|
||||||
return prismjs.highlight(str, prismjs.languages[language]);
|
return prismjs.highlight(str, prismjs.languages[language]);
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hljs.getLanguage(lang)) {
|
if (hljs.getLanguage(lang)) {
|
||||||
return hljs.highlight(lang, str).value;
|
return hljs.highlight(lang, str).value;
|
||||||
}
|
}
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return hljs.highlightAuto(str).value;
|
return hljs.highlightAuto(str).value;
|
||||||
} catch (err) {}
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
|
@ -70,11 +76,11 @@ class MarkdownRenderer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this._md = md;
|
this.md = md;
|
||||||
}
|
}
|
||||||
|
|
||||||
toHtml(source) {
|
toHtml(source) {
|
||||||
const html = this._md.render(source);
|
const html = this.md.render(source);
|
||||||
|
|
||||||
// Ensure fenced code blocks use Highlight.js hljs class
|
// Ensure fenced code blocks use Highlight.js hljs class
|
||||||
// https://github.com/jonschlinkert/remarkable/issues/224
|
// https://github.com/jonschlinkert/remarkable/issues/224
|
||||||
|
|
|
@ -26,12 +26,11 @@ function removeExtension(path) {
|
||||||
|
|
||||||
function getPath(path, cleanUrl = false) {
|
function getPath(path, cleanUrl = false) {
|
||||||
if (cleanUrl) {
|
if (cleanUrl) {
|
||||||
if (path.endsWith('/index.html')) {
|
return path.endsWith('/index.html')
|
||||||
return path.replace(/\/index.html$/, '');
|
? path.replace(/\/index.html$/, '')
|
||||||
} else {
|
: removeExtension(path);
|
||||||
return removeExtension(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,7 @@ if (defaultBranch !== DEPLOYMENT_BRANCH) {
|
||||||
shell.echo(`Error: Git checkout ${DEPLOYMENT_BRANCH} failed`);
|
shell.echo(`Error: Git checkout ${DEPLOYMENT_BRANCH} failed`);
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (
|
||||||
if (
|
|
||||||
shell.exec(`git checkout -b ${DEPLOYMENT_BRANCH}`).code +
|
shell.exec(`git checkout -b ${DEPLOYMENT_BRANCH}`).code +
|
||||||
shell.exec(`git branch --set-upstream-to=origin/${DEPLOYMENT_BRANCH}`)
|
shell.exec(`git branch --set-upstream-to=origin/${DEPLOYMENT_BRANCH}`)
|
||||||
.code !==
|
.code !==
|
||||||
|
@ -122,7 +121,6 @@ if (defaultBranch !== DEPLOYMENT_BRANCH) {
|
||||||
shell.exit(1);
|
shell.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
shell.exec('git rm -rf .');
|
shell.exec('git rm -rf .');
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ const excludePath = `${PROJECT_NAME}-${DEPLOYMENT_BRANCH}`;
|
||||||
fs.copy(
|
fs.copy(
|
||||||
fromPath,
|
fromPath,
|
||||||
toPath,
|
toPath,
|
||||||
(src, dest) => {
|
src => {
|
||||||
if (src.indexOf('.DS_Store') !== -1) {
|
if (src.indexOf('.DS_Store') !== -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const program = require('commander');
|
||||||
|
const escapeStringRegexp = require('escape-string-regexp');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const metadataUtils = require('./server/metadataUtils.js');
|
const metadataUtils = require('./server/metadataUtils.js');
|
||||||
|
|
||||||
const CWD = process.cwd();
|
const CWD = process.cwd();
|
||||||
|
|
||||||
// escape appropriate characters in a string to be used in a regex
|
|
||||||
RegExp.escape = function(s) {
|
|
||||||
return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
||||||
};
|
|
||||||
|
|
||||||
// generate a doc header from metadata
|
// generate a doc header from metadata
|
||||||
function makeHeader(metadata) {
|
function makeHeader(metadata) {
|
||||||
let header = '---\n';
|
let header = '---\n';
|
||||||
|
@ -30,9 +28,8 @@ function makeHeader(metadata) {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentVersion, newVersion;
|
let currentVersion;
|
||||||
|
let newVersion;
|
||||||
const program = require('commander');
|
|
||||||
|
|
||||||
program
|
program
|
||||||
.arguments('<version_name> <new_version_name>')
|
.arguments('<version_name> <new_version_name>')
|
||||||
|
@ -123,7 +120,7 @@ if (fs.existsSync(currentSidebarFile)) {
|
||||||
fs.renameSync(currentSidebarFile, newSidebarFile);
|
fs.renameSync(currentSidebarFile, newSidebarFile);
|
||||||
let sidebarContent = fs.readFileSync(newSidebarFile, 'utf8');
|
let sidebarContent = fs.readFileSync(newSidebarFile, 'utf8');
|
||||||
sidebarContent = sidebarContent.replace(
|
sidebarContent = sidebarContent.replace(
|
||||||
new RegExp(`version-${RegExp.escape(currentVersion)}-`, 'g'),
|
new RegExp(`version-${escapeStringRegexp(currentVersion)}-`, 'g'),
|
||||||
`version-${newVersion}-`
|
`version-${newVersion}-`
|
||||||
);
|
);
|
||||||
fs.writeFileSync(newSidebarFile, sidebarContent);
|
fs.writeFileSync(newSidebarFile, sidebarContent);
|
||||||
|
|
|
@ -13,9 +13,9 @@ const siteConfig = require(CWD + '/siteConfig.js');
|
||||||
|
|
||||||
const join = path.join;
|
const join = path.join;
|
||||||
|
|
||||||
const languages_js = join(CWD, 'languages.js');
|
const languagesFile = join(CWD, 'languages.js');
|
||||||
const versions_json = join(CWD, 'versions.json');
|
const versionsJSONFile = join(CWD, 'versions.json');
|
||||||
const versions_js = join(CWD, 'pages/en/versions.js');
|
const versionsFile = join(CWD, 'pages/en/versions.js');
|
||||||
|
|
||||||
class Translation {
|
class Translation {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -28,17 +28,15 @@ class Translation {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
this._load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledLanguages() {
|
enabledLanguages = () => this.languages.filter(lang => lang.enabled);
|
||||||
return this.languages.filter(lang => lang.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
_load() {
|
load() {
|
||||||
if (fs.existsSync(languages_js)) {
|
if (fs.existsSync(languagesFile)) {
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
this.languages = require(languages_js);
|
this.languages = require(languagesFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +48,7 @@ class Versioning {
|
||||||
this.versions = [];
|
this.versions = [];
|
||||||
this.missingVersionsPage = false;
|
this.missingVersionsPage = false;
|
||||||
|
|
||||||
this._load();
|
this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
printMissingVersionsPageError() {
|
printMissingVersionsPageError() {
|
||||||
|
@ -61,16 +59,16 @@ class Versioning {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_load() {
|
load() {
|
||||||
if (fs.existsSync(versions_json)) {
|
if (fs.existsSync(versionsJSONFile)) {
|
||||||
this.enabled = true;
|
this.enabled = true;
|
||||||
this.versions = JSON.parse(fs.readFileSync(versions_json, 'utf8'));
|
this.versions = JSON.parse(fs.readFileSync(versionsJSONFile, 'utf8'));
|
||||||
this.defaultVersion = siteConfig.defaultVersionShown
|
this.defaultVersion = siteConfig.defaultVersionShown
|
||||||
? siteConfig.defaultVersionShown
|
? siteConfig.defaultVersionShown
|
||||||
: this.versions[0]; // otherwise show the latest version (other than next/master)
|
: this.versions[0]; // otherwise show the latest version (other than next/master)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(versions_js)) {
|
if (!fs.existsSync(versionsFile)) {
|
||||||
this.missingVersionsPage = true;
|
this.missingVersionsPage = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,13 +137,11 @@ async function execute() {
|
||||||
} else {
|
} else {
|
||||||
file = join(CWD, 'versioned_docs', metadata.source);
|
file = join(CWD, 'versioned_docs', metadata.source);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (metadata.language === 'en') {
|
||||||
if (metadata.language === 'en') {
|
|
||||||
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
|
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
|
||||||
} else {
|
} else {
|
||||||
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
|
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(file)) {
|
if (!fs.existsSync(file)) {
|
||||||
return;
|
return;
|
||||||
|
@ -156,14 +154,14 @@ async function execute() {
|
||||||
const language = metadata.language;
|
const language = metadata.language;
|
||||||
|
|
||||||
// generate table of contents if appropriate
|
// generate table of contents if appropriate
|
||||||
if (rawContent && rawContent.indexOf(TABLE_OF_CONTENTS_TOKEN) != -1) {
|
if (rawContent && rawContent.indexOf(TABLE_OF_CONTENTS_TOKEN) !== -1) {
|
||||||
rawContent = insertTableOfContents(rawContent);
|
rawContent = insertTableOfContents(rawContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
let defaultVersion = env.versioning.defaultVersion;
|
let defaultVersion = env.versioning.defaultVersion;
|
||||||
|
|
||||||
// replace any links to markdown files to their website html links
|
// replace any links to markdown files to their website html links
|
||||||
Object.keys(mdToHtml).forEach(function(key, index) {
|
Object.keys(mdToHtml).forEach(key => {
|
||||||
let link = mdToHtml[key];
|
let link = mdToHtml[key];
|
||||||
link = utils.getPath(link, siteConfig.cleanUrl);
|
link = utils.getPath(link, siteConfig.cleanUrl);
|
||||||
link = link.replace('/en/', '/' + language + '/');
|
link = link.replace('/en/', '/' + language + '/');
|
||||||
|
@ -489,18 +487,16 @@ async function execute() {
|
||||||
const match = regexLang.exec(normalizedFile);
|
const match = regexLang.exec(normalizedFile);
|
||||||
const langParts = match[1].split(sep);
|
const langParts = match[1].split(sep);
|
||||||
if (langParts.indexOf('en') !== -1) {
|
if (langParts.indexOf('en') !== -1) {
|
||||||
// copy and compile a page for each enabled language from the English file
|
// Copy and compile a page for each enabled language from the English file.
|
||||||
for (let i = 0; i < enabledLanguages.length; i++) {
|
for (let i = 0; i < enabledLanguages.length; i++) {
|
||||||
let language = enabledLanguages[i];
|
const language = enabledLanguages[i];
|
||||||
// skip conversion from english file if a file exists for this language
|
// Skip conversion from English file if a file exists for this language.
|
||||||
if (
|
if (
|
||||||
language !== 'en' &&
|
language === 'en' ||
|
||||||
fs.existsSync(
|
!fs.existsSync(
|
||||||
normalizedFile.replace(sep + 'en' + sep, sep + language + sep)
|
normalizedFile.replace(sep + 'en' + sep, sep + language + sep)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
translate.setLanguage(language);
|
translate.setLanguage(language);
|
||||||
const str = renderToStaticMarkupWithDoctype(
|
const str = renderToStaticMarkupWithDoctype(
|
||||||
<Site
|
<Site
|
||||||
|
@ -518,6 +514,7 @@ async function execute() {
|
||||||
str
|
str
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// write to base level
|
// write to base level
|
||||||
let language = env.translation.enabled ? 'en' : '';
|
let language = env.translation.enabled ? 'en' : '';
|
||||||
|
|
|
@ -55,7 +55,9 @@ function extractMetadata(content) {
|
||||||
.trim();
|
.trim();
|
||||||
try {
|
try {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
} catch (e) {}
|
} catch (err) {
|
||||||
|
// Ignore the error as it means it's not a JSON value.
|
||||||
|
}
|
||||||
metadata[key] = value;
|
metadata[key] = value;
|
||||||
}
|
}
|
||||||
return {metadata, rawContent: both.content};
|
return {metadata, rawContent: both.content};
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const CWD = process.cwd();
|
const fs = require('fs');
|
||||||
|
|
||||||
const Metadata = require('../core/metadata.js');
|
const Metadata = require('../core/metadata.js');
|
||||||
const fs = require('fs');
|
|
||||||
|
const CWD = process.cwd();
|
||||||
let languages;
|
let languages;
|
||||||
if (fs.existsSync(CWD + '/languages.js')) {
|
if (fs.existsSync(CWD + '/languages.js')) {
|
||||||
languages = require(CWD + '/languages.js');
|
languages = require(CWD + '/languages.js');
|
||||||
|
@ -24,10 +25,9 @@ if (fs.existsSync(CWD + '/languages.js')) {
|
||||||
|
|
||||||
// returns data broken up into categories for a sidebar
|
// returns data broken up into categories for a sidebar
|
||||||
function readCategories(sidebar) {
|
function readCategories(sidebar) {
|
||||||
const enabledLanguages = [];
|
const enabledLanguages = languages
|
||||||
languages.filter(lang => lang.enabled).map(lang => {
|
.filter(lang => lang.enabled)
|
||||||
enabledLanguages.push(lang.tag);
|
.map(lang => lang.tag);
|
||||||
});
|
|
||||||
|
|
||||||
const allCategories = {};
|
const allCategories = {};
|
||||||
|
|
||||||
|
@ -88,7 +88,9 @@ function readCategories(sidebar) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (metadata && i++ < 1000) {
|
while (metadata && i++ < 1000) {
|
||||||
if (!currentCategory || metadata.category !== currentCategory.name) {
|
if (!currentCategory || metadata.category !== currentCategory.name) {
|
||||||
currentCategory && categories.push(currentCategory);
|
if (currentCategory) {
|
||||||
|
categories.push(currentCategory);
|
||||||
|
}
|
||||||
currentCategory = {
|
currentCategory = {
|
||||||
name: metadata.category,
|
name: metadata.category,
|
||||||
links: [],
|
links: [],
|
||||||
|
|
|
@ -66,7 +66,8 @@ function readSidebar() {
|
||||||
|
|
||||||
for (let i = 0; i < ids.length; i++) {
|
for (let i = 0; i < ids.length; i++) {
|
||||||
const id = ids[i];
|
const id = ids[i];
|
||||||
let previous, next;
|
let previous;
|
||||||
|
let next;
|
||||||
if (i > 0) previous = ids[i - 1];
|
if (i > 0) previous = ids[i - 1];
|
||||||
if (i < ids.length - 1) next = ids[i + 1];
|
if (i < ids.length - 1) next = ids[i + 1];
|
||||||
order[id] = {
|
order[id] = {
|
||||||
|
@ -86,13 +87,13 @@ function processMetadata(file, refDir) {
|
||||||
const language = utils.getLanguage(file, refDir) || 'en';
|
const language = utils.getLanguage(file, refDir) || 'en';
|
||||||
|
|
||||||
const metadata = {};
|
const metadata = {};
|
||||||
for (const fieldName of Object.keys(result.metadata)) {
|
Object.keys(result.metadata).forEach(fieldName => {
|
||||||
if (SupportedHeaderFields.has(fieldName)) {
|
if (SupportedHeaderFields.has(fieldName)) {
|
||||||
metadata[fieldName] = result.metadata[fieldName];
|
metadata[fieldName] = result.metadata[fieldName];
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Header field "${fieldName}" in ${file} is not supported.`);
|
console.warn(`Header field "${fieldName}" in ${file} is not supported.`);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
const rawContent = result.rawContent;
|
const rawContent = result.rawContent;
|
||||||
|
|
||||||
|
@ -193,10 +194,8 @@ function generateMetadataDocs() {
|
||||||
// create a default list of documents for each enabled language based on docs in English
|
// create a default list of documents for each enabled language based on docs in English
|
||||||
// these will get replaced if/when the localized file is downloaded from crowdin
|
// these will get replaced if/when the localized file is downloaded from crowdin
|
||||||
enabledLanguages
|
enabledLanguages
|
||||||
.filter(currentLanguage => {
|
.filter(currentLanguage => currentLanguage !== 'en')
|
||||||
return currentLanguage != 'en';
|
.forEach(currentLanguage => {
|
||||||
})
|
|
||||||
.map(currentLanguage => {
|
|
||||||
let baseMetadata = Object.assign({}, metadata);
|
let baseMetadata = Object.assign({}, metadata);
|
||||||
baseMetadata['id'] = baseMetadata['id']
|
baseMetadata['id'] = baseMetadata['id']
|
||||||
.toString()
|
.toString()
|
||||||
|
@ -291,7 +290,7 @@ function generateMetadataDocs() {
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
__dirname + '/../core/metadata.js',
|
path.join(__dirname, '/../core/metadata.js'),
|
||||||
'/**\n' +
|
'/**\n' +
|
||||||
' * @' +
|
' * @' +
|
||||||
'generated\n' + // separate this out for Nuclide treating @generated as readonly
|
'generated\n' + // separate this out for Nuclide treating @generated as readonly
|
||||||
|
@ -360,7 +359,7 @@ function generateMetadataBlog() {
|
||||||
);
|
);
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
__dirname + '/../core/MetadataBlog.js',
|
path.join(__dirname, '/../core/MetadataBlog.js'),
|
||||||
'/**\n' +
|
'/**\n' +
|
||||||
' * @' +
|
' * @' +
|
||||||
'generated\n' + // separate this out for Nuclide treating @generated as readonly
|
'generated\n' + // separate this out for Nuclide treating @generated as readonly
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-cond-assign */
|
||||||
|
|
||||||
function execute(port, options) {
|
function execute(port, options) {
|
||||||
const extractTranslations = require('../write-translations');
|
const extractTranslations = require('../write-translations');
|
||||||
|
|
||||||
|
@ -45,8 +47,18 @@ function execute(port, options) {
|
||||||
const join = path.join;
|
const join = path.join;
|
||||||
const sep = path.sep;
|
const sep = path.sep;
|
||||||
|
|
||||||
// remove a module and child modules from require cache, so server does not have
|
function removeModulePathFromCache(moduleName) {
|
||||||
// to be restarted
|
/* eslint-disable no-underscore-dangle */
|
||||||
|
Object.keys(module.constructor._pathCache).forEach(function(cacheKey) {
|
||||||
|
if (cacheKey.indexOf(moduleName) > 0) {
|
||||||
|
delete module.constructor._pathCache[cacheKey];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* eslint-enable no-underscore-dangle */
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a module and child modules from require cache, so server
|
||||||
|
// does not have to be restarted.
|
||||||
function removeModuleAndChildrenFromCache(moduleName) {
|
function removeModuleAndChildrenFromCache(moduleName) {
|
||||||
let mod = require.resolve(moduleName);
|
let mod = require.resolve(moduleName);
|
||||||
if (mod && (mod = require.cache[mod])) {
|
if (mod && (mod = require.cache[mod])) {
|
||||||
|
@ -59,14 +71,6 @@ function execute(port, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeModulePathFromCache(moduleName) {
|
|
||||||
Object.keys(module.constructor._pathCache).forEach(function(cacheKey) {
|
|
||||||
if (cacheKey.indexOf(moduleName) > 0) {
|
|
||||||
delete module.constructor._pathCache[cacheKey];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
let readMetadata = require('./readMetadata.js');
|
let readMetadata = require('./readMetadata.js');
|
||||||
|
@ -147,6 +151,36 @@ function execute(port, options) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startLiveReload() {
|
||||||
|
// Start LiveReload server.
|
||||||
|
process.env.NODE_ENV = 'development';
|
||||||
|
const server = tinylr();
|
||||||
|
server.listen(constants.LIVE_RELOAD_PORT, function() {
|
||||||
|
console.log(
|
||||||
|
'LiveReload server started on port %d',
|
||||||
|
constants.LIVE_RELOAD_PORT
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// gaze watches some specified dirs and triggers a callback when they change.
|
||||||
|
gaze(
|
||||||
|
[
|
||||||
|
'../' + readMetadata.getDocsPath() + '/**/*', // docs
|
||||||
|
'**/*', // website
|
||||||
|
'!node_modules/**/*', // node_modules
|
||||||
|
],
|
||||||
|
function() {
|
||||||
|
// Listen for all kinds of file changes - modified/added/deleted.
|
||||||
|
this.on('all', function() {
|
||||||
|
// Notify LiveReload clients that there's a change.
|
||||||
|
// Typically, LiveReload will only refresh the changed paths,
|
||||||
|
// so we use / here to force a full-page reload.
|
||||||
|
server.notifyClients(['/']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
reloadMetadata();
|
reloadMetadata();
|
||||||
|
@ -200,13 +234,11 @@ function execute(port, options) {
|
||||||
} else {
|
} else {
|
||||||
file = join(CWD, 'versioned_docs', metadata.source);
|
file = join(CWD, 'versioned_docs', metadata.source);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!env.translation.enabled || metadata.language === 'en') {
|
||||||
if (!env.translation.enabled || metadata.language === 'en') {
|
|
||||||
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
|
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
|
||||||
} else {
|
} else {
|
||||||
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
|
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(file)) {
|
if (!fs.existsSync(file)) {
|
||||||
next();
|
next();
|
||||||
|
@ -225,7 +257,7 @@ function execute(port, options) {
|
||||||
let defaultVersion = env.versioning.defaultVersion;
|
let defaultVersion = env.versioning.defaultVersion;
|
||||||
|
|
||||||
// replace any links to markdown files to their website html links
|
// replace any links to markdown files to their website html links
|
||||||
Object.keys(mdToHtml).forEach(function(key, index) {
|
Object.keys(mdToHtml).forEach(key => {
|
||||||
let link = mdToHtml[key];
|
let link = mdToHtml[key];
|
||||||
link = utils.getPath(link, siteConfig.cleanUrl);
|
link = utils.getPath(link, siteConfig.cleanUrl);
|
||||||
link = link.replace('/en/', '/' + language + '/');
|
link = link.replace('/en/', '/' + language + '/');
|
||||||
|
@ -333,8 +365,8 @@ function execute(port, options) {
|
||||||
);
|
);
|
||||||
const str = renderToStaticMarkupWithDoctype(blogPageComp);
|
const str = renderToStaticMarkupWithDoctype(blogPageComp);
|
||||||
|
|
||||||
let path = (page > 0 ? 'page' + (page + 1) : '') + '/index.html';
|
const pagePath = (page > 0 ? 'page' + (page + 1) : '') + '/index.html';
|
||||||
blogPages[path] = str;
|
blogPages[pagePath] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
let parts = req.path.toString().split('blog/');
|
let parts = req.path.toString().split('blog/');
|
||||||
|
@ -398,7 +430,7 @@ function execute(port, options) {
|
||||||
|
|
||||||
// handle all other main pages
|
// handle all other main pages
|
||||||
app.get(pageRouting(siteConfig.baseUrl), (req, res, next) => {
|
app.get(pageRouting(siteConfig.baseUrl), (req, res, next) => {
|
||||||
// look for user provided html file first
|
// Look for user-provided HTML file first.
|
||||||
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
|
let htmlFile = req.path.toString().replace(siteConfig.baseUrl, '');
|
||||||
htmlFile = join(CWD, 'pages', htmlFile);
|
htmlFile = join(CWD, 'pages', htmlFile);
|
||||||
if (
|
if (
|
||||||
|
@ -470,8 +502,8 @@ function execute(port, options) {
|
||||||
fs.existsSync((userFile = englishFile))
|
fs.existsSync((userFile = englishFile))
|
||||||
) {
|
) {
|
||||||
// copy into docusaurus so require paths work
|
// copy into docusaurus so require paths work
|
||||||
let parts = userFile.split('pages' + sep);
|
let userFileParts = userFile.split('pages' + sep);
|
||||||
let tempFile = join(__dirname, '..', 'pages', parts[1]);
|
let tempFile = join(__dirname, '..', 'pages', userFileParts[1]);
|
||||||
tempFile = tempFile.replace(
|
tempFile = tempFile.replace(
|
||||||
path.basename(file),
|
path.basename(file),
|
||||||
'temp' + path.basename(file)
|
'temp' + path.basename(file)
|
||||||
|
@ -501,7 +533,6 @@ function execute(port, options) {
|
||||||
res.send(str);
|
res.send(str);
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -598,36 +629,6 @@ function execute(port, options) {
|
||||||
|
|
||||||
if (options.watch) startLiveReload();
|
if (options.watch) startLiveReload();
|
||||||
app.listen(port);
|
app.listen(port);
|
||||||
|
|
||||||
function startLiveReload() {
|
|
||||||
// Start LiveReload server.
|
|
||||||
process.env.NODE_ENV = 'development';
|
|
||||||
const server = tinylr();
|
|
||||||
server.listen(constants.LIVE_RELOAD_PORT, function() {
|
|
||||||
console.log(
|
|
||||||
'LiveReload server started on port %d',
|
|
||||||
constants.LIVE_RELOAD_PORT
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// gaze watches some specified dirs and triggers a callback when they change.
|
|
||||||
gaze(
|
|
||||||
[
|
|
||||||
'../' + readMetadata.getDocsPath() + '/**/*', // docs
|
|
||||||
'**/*', // website
|
|
||||||
'!node_modules/**/*', // node_modules
|
|
||||||
],
|
|
||||||
function() {
|
|
||||||
// Listen for all kinds of file changes - modified/added/deleted.
|
|
||||||
this.on('all', function() {
|
|
||||||
// Notify LiveReload clients that there's a change.
|
|
||||||
// Typically, LiveReload will only refresh the changed paths,
|
|
||||||
// so we use / here to force a full-page reload.
|
|
||||||
server.notifyClients(['/']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = execute;
|
module.exports = execute;
|
||||||
|
|
|
@ -32,8 +32,6 @@ MetadataBlog = require('../core/MetadataBlog.js');
|
||||||
module.exports = function(callback) {
|
module.exports = function(callback) {
|
||||||
console.log('sitemap.js triggered...');
|
console.log('sitemap.js triggered...');
|
||||||
|
|
||||||
let urls = [];
|
|
||||||
|
|
||||||
let files = glob.sync(CWD + '/pages/en/**/*.js');
|
let files = glob.sync(CWD + '/pages/en/**/*.js');
|
||||||
|
|
||||||
// English-only is the default.
|
// English-only is the default.
|
||||||
|
@ -48,25 +46,23 @@ module.exports = function(callback) {
|
||||||
// If we have a languages.js file, get all the enabled languages in there
|
// If we have a languages.js file, get all the enabled languages in there
|
||||||
if (fs.existsSync(CWD + '/languages.js')) {
|
if (fs.existsSync(CWD + '/languages.js')) {
|
||||||
let languages = require(CWD + '/languages.js');
|
let languages = require(CWD + '/languages.js');
|
||||||
enabledLanguages = languages.filter(lang => {
|
enabledLanguages = languages.filter(lang => lang.enabled);
|
||||||
return lang.enabled == true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a url mapping to all the enabled languages files
|
// Create a url mapping to all the enabled languages files
|
||||||
files.map(file => {
|
const urls = files.map(file => {
|
||||||
let url = file.split('/pages/en')[1];
|
let url = file.split('/pages/en')[1];
|
||||||
url = siteConfig.cleanUrl
|
url = siteConfig.cleanUrl
|
||||||
? url.replace(/\.js$/, '')
|
? url.replace(/\.js$/, '')
|
||||||
: url.replace(/\.js$/, '.html');
|
: url.replace(/\.js$/, '.html');
|
||||||
let links = enabledLanguages.map(lang => {
|
const links = enabledLanguages.map(lang => {
|
||||||
let langUrl = lang.tag + url;
|
let langUrl = lang.tag + url;
|
||||||
return {lang: lang.tag, url: langUrl};
|
return {lang: lang.tag, url: langUrl};
|
||||||
});
|
});
|
||||||
urls.push({url, changefreq: 'weekly', priority: 0.5, links});
|
return {url, changefreq: 'weekly', priority: 0.5, links};
|
||||||
});
|
});
|
||||||
|
|
||||||
MetadataBlog.map(blog => {
|
MetadataBlog.forEach(blog => {
|
||||||
urls.push({
|
urls.push({
|
||||||
url: '/blog/' + utils.getPath(blog.path, siteConfig.cleanUrl),
|
url: '/blog/' + utils.getPath(blog.path, siteConfig.cleanUrl),
|
||||||
changefreq: 'weekly',
|
changefreq: 'weekly',
|
||||||
|
@ -76,7 +72,7 @@ module.exports = function(callback) {
|
||||||
|
|
||||||
Object.keys(Metadata)
|
Object.keys(Metadata)
|
||||||
.filter(key => Metadata[key].language === 'en')
|
.filter(key => Metadata[key].language === 'en')
|
||||||
.map(key => {
|
.forEach(key => {
|
||||||
let doc = Metadata[key];
|
let doc = Metadata[key];
|
||||||
let docUrl = utils.getPath(doc.permalink, siteConfig.cleanUrl);
|
let docUrl = utils.getPath(doc.permalink, siteConfig.cleanUrl);
|
||||||
let links = enabledLanguages.map(lang => {
|
let links = enabledLanguages.map(lang => {
|
||||||
|
@ -94,7 +90,7 @@ module.exports = function(callback) {
|
||||||
const sm = sitemap.createSitemap({
|
const sm = sitemap.createSitemap({
|
||||||
hostname: siteConfig.url,
|
hostname: siteConfig.url,
|
||||||
cacheTime: 600 * 1000, // 600 sec - cache purge period
|
cacheTime: 600 * 1000, // 600 sec - cache purge period
|
||||||
urls: urls,
|
urls,
|
||||||
});
|
});
|
||||||
|
|
||||||
sm.toXML((err, xml) => {
|
sm.toXML((err, xml) => {
|
||||||
|
|
|
@ -25,8 +25,8 @@ module.exports = function translatePlugin(babel) {
|
||||||
description = attributes[i].value.value;
|
description = attributes[i].value.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* use an expression container if inside a jsxelement */
|
/* use an expression container if inside a JSXElement */
|
||||||
if (path.findParent(path => true).node.type === 'JSXElement') {
|
if (path.findParent(() => true).node.type === 'JSXElement') {
|
||||||
path.replaceWith(
|
path.replaceWith(
|
||||||
t.jSXExpressionContainer(
|
t.jSXExpressionContainer(
|
||||||
t.callExpression(t.identifier('translate'), [
|
t.callExpression(t.identifier('translate'), [
|
||||||
|
|
|
@ -96,7 +96,7 @@ files.forEach(file => {
|
||||||
|
|
||||||
// returns the version to use for a document based on its id and
|
// returns the version to use for a document based on its id and
|
||||||
// what the requested version is
|
// what the requested version is
|
||||||
function docVersion(id, req_version) {
|
function docVersion(id, reqVersion) {
|
||||||
if (!available[id]) {
|
if (!available[id]) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -104,13 +104,10 @@ function docVersion(id, req_version) {
|
||||||
// is found, then check if that version has an available file to use
|
// is found, then check if that version has an available file to use
|
||||||
let requestedFound = false;
|
let requestedFound = false;
|
||||||
for (let i = 0; i < versions.length; i++) {
|
for (let i = 0; i < versions.length; i++) {
|
||||||
if (versions[i] === req_version) {
|
if (versions[i] === reqVersion) {
|
||||||
requestedFound = true;
|
requestedFound = true;
|
||||||
}
|
}
|
||||||
if (!requestedFound) {
|
if (requestedFound && available[id].has(versions[i])) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (available[id].has(versions[i])) {
|
|
||||||
return versions[i];
|
return versions[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,18 +240,16 @@ function docData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the version of the sidebar to use given a requested version
|
// return the version of the sidebar to use given a requested version
|
||||||
function sidebarVersion(req_version) {
|
function sidebarVersion(reqVersion) {
|
||||||
// iterate through versions until a version less than or equal to the requested
|
// iterate through versions until a version less than or equal to the requested
|
||||||
// is found, then check if that version has an available file to use
|
// is found, then check if that version has an available file to use
|
||||||
let requestedFound = false;
|
let requestedFound = false;
|
||||||
for (let i = 0; i < versions.length; i++) {
|
for (let i = 0; i < versions.length; i++) {
|
||||||
if (versions[i] === req_version) {
|
if (versions[i] === reqVersion) {
|
||||||
requestedFound = true;
|
requestedFound = true;
|
||||||
}
|
}
|
||||||
if (!requestedFound) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (
|
if (
|
||||||
|
requestedFound &&
|
||||||
fs.existsSync(
|
fs.existsSync(
|
||||||
CWD + '/versioned_sidebars/version-' + versions[i] + '-sidebars.json'
|
CWD + '/versioned_sidebars/version-' + versions[i] + '-sidebars.json'
|
||||||
)
|
)
|
||||||
|
@ -263,7 +258,7 @@ function sidebarVersion(req_version) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`No sidebar file available to use for version ${req_version}. Verify that 'version-${req_version}-sidebars.json' exists.`
|
`No sidebar file available to use for version ${reqVersion}. Verify that 'version-${reqVersion}-sidebars.json' exists.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,12 @@ require('babel-register')({
|
||||||
presets: ['react', 'env'],
|
presets: ['react', 'env'],
|
||||||
});
|
});
|
||||||
|
|
||||||
// For verifying port usage
|
|
||||||
const tcpPortUsed = require('tcp-port-used');
|
|
||||||
|
|
||||||
// initial check that required files are present
|
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const program = require('commander');
|
||||||
const openBrowser = require('react-dev-utils/openBrowser');
|
const openBrowser = require('react-dev-utils/openBrowser');
|
||||||
|
const tcpPortUsed = require('tcp-port-used');
|
||||||
|
|
||||||
const CWD = process.cwd();
|
const CWD = process.cwd();
|
||||||
const env = require('./server/env.js');
|
const env = require('./server/env.js');
|
||||||
|
|
||||||
|
@ -40,8 +39,6 @@ if (env.versioning.enabled && env.versioning.missingVersionsPage) {
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const program = require('commander');
|
|
||||||
|
|
||||||
program
|
program
|
||||||
.option('--port <number>', 'Specify port number')
|
.option('--port <number>', 'Specify port number')
|
||||||
.option('--no-watch', 'Toggle live reload file watching')
|
.option('--no-watch', 'Toggle live reload file watching')
|
||||||
|
@ -50,7 +47,6 @@ program
|
||||||
let port = parseInt(program.port, 10) || process.env.PORT || 3000;
|
let port = parseInt(program.port, 10) || process.env.PORT || 3000;
|
||||||
let numAttempts = 0;
|
let numAttempts = 0;
|
||||||
const MAX_ATTEMPTS = 10;
|
const MAX_ATTEMPTS = 10;
|
||||||
checkPort();
|
|
||||||
|
|
||||||
function checkPort() {
|
function checkPort() {
|
||||||
tcpPortUsed
|
tcpPortUsed
|
||||||
|
@ -84,3 +80,5 @@ function checkPort() {
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkPort();
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const program = require('commander');
|
||||||
|
const chalk = require('chalk');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('path');
|
|
||||||
const mkdirp = require('mkdirp');
|
const mkdirp = require('mkdirp');
|
||||||
const chalk = require('chalk');
|
const path = require('path');
|
||||||
|
|
||||||
const readMetadata = require('./server/readMetadata.js');
|
const readMetadata = require('./server/readMetadata.js');
|
||||||
const utils = require('./server/utils.js');
|
const utils = require('./server/utils.js');
|
||||||
const versionFallback = require('./server/versionFallback.js');
|
const versionFallback = require('./server/versionFallback.js');
|
||||||
|
@ -28,7 +30,6 @@ if (fs.existsSync(CWD + '/versions.json')) {
|
||||||
|
|
||||||
let version;
|
let version;
|
||||||
|
|
||||||
const program = require('commander');
|
|
||||||
program
|
program
|
||||||
.arguments('<version>')
|
.arguments('<version>')
|
||||||
.action(ver => {
|
.action(ver => {
|
||||||
|
@ -130,16 +131,18 @@ if (versionFallback.diffLatestSidebar()) {
|
||||||
const versioned = {};
|
const versioned = {};
|
||||||
|
|
||||||
Object.keys(sidebar).forEach(sb => {
|
Object.keys(sidebar).forEach(sb => {
|
||||||
const version_sb = 'version-' + version + '-' + sb;
|
const versionSidebar = 'version-' + version + '-' + sb;
|
||||||
versioned[version_sb] = {};
|
versioned[versionSidebar] = {};
|
||||||
|
|
||||||
const categories = sidebar[sb];
|
const categories = sidebar[sb];
|
||||||
Object.keys(categories).forEach(category => {
|
Object.keys(categories).forEach(category => {
|
||||||
versioned[version_sb][category] = [];
|
versioned[versionSidebar][category] = [];
|
||||||
|
|
||||||
const ids = categories[category];
|
const ids = categories[category];
|
||||||
ids.forEach((id, index) => {
|
ids.forEach(id => {
|
||||||
versioned[version_sb][category].push('version-' + version + '-' + id);
|
versioned[versionSidebar][category].push(
|
||||||
|
'version-' + version + '-' + id
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
|
|
||||||
/* generate the i18n/en.json file */
|
/* generate the i18n/en.json file */
|
||||||
|
|
||||||
const CWD = process.cwd();
|
|
||||||
const fs = require('fs-extra');
|
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
const glob = require('glob');
|
|
||||||
const readMetadata = require('./server/readMetadata.js');
|
|
||||||
const path = require('path');
|
|
||||||
const siteConfig = require(CWD + '/siteConfig.js');
|
|
||||||
const babylon = require('babylon');
|
|
||||||
const traverse = require('babel-traverse').default;
|
const traverse = require('babel-traverse').default;
|
||||||
|
const babylon = require('babylon');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const glob = require('glob');
|
||||||
|
const mkdirp = require('mkdirp');
|
||||||
|
const nodePath = require('path');
|
||||||
|
|
||||||
|
const readMetadata = require('./server/readMetadata.js');
|
||||||
|
const CWD = process.cwd();
|
||||||
|
const siteConfig = require(CWD + '/siteConfig.js');
|
||||||
const sidebars = require(CWD + '/sidebars.json');
|
const sidebars = require(CWD + '/sidebars.json');
|
||||||
|
|
||||||
let customTranslations = {
|
let customTranslations = {
|
||||||
|
@ -46,10 +47,10 @@ function execute() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// look through markdown headers of docs for titles and categories to translate
|
// look through markdown headers of docs for titles and categories to translate
|
||||||
const docsDir = path.join(CWD, '../', readMetadata.getDocsPath());
|
const docsDir = nodePath.join(CWD, '../', readMetadata.getDocsPath());
|
||||||
let files = glob.sync(CWD + '/../' + readMetadata.getDocsPath() + '/**');
|
let files = glob.sync(CWD + '/../' + readMetadata.getDocsPath() + '/**');
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
const extension = path.extname(file);
|
const extension = nodePath.extname(file);
|
||||||
if (extension === '.md' || extension === '.markdown') {
|
if (extension === '.md' || extension === '.markdown') {
|
||||||
let res;
|
let res;
|
||||||
try {
|
try {
|
||||||
|
@ -115,7 +116,7 @@ function execute() {
|
||||||
// go through pages to look for text inside translate tags
|
// go through pages to look for text inside translate tags
|
||||||
files = glob.sync(CWD + '/pages/en/**');
|
files = glob.sync(CWD + '/pages/en/**');
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
const extension = path.extname(file);
|
const extension = nodePath.extname(file);
|
||||||
if (extension === '.js') {
|
if (extension === '.js') {
|
||||||
const ast = babylon.parse(fs.readFileSync(file, 'utf8'), {
|
const ast = babylon.parse(fs.readFileSync(file, 'utf8'), {
|
||||||
plugins: ['jsx'],
|
plugins: ['jsx'],
|
||||||
|
|
|
@ -5,29 +5,56 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const React = require("react");
|
/* eslint-disable react/jsx-no-comment-textnodes */
|
||||||
const CompLibrary = require("../../core/CompLibrary.js");
|
|
||||||
|
const React = require('react');
|
||||||
|
const CompLibrary = require('../../core/CompLibrary.js');
|
||||||
const Container = CompLibrary.Container;
|
const Container = CompLibrary.Container;
|
||||||
const GridBlock = CompLibrary.GridBlock;
|
const siteConfig = require(process.cwd() + '/siteConfig.js');
|
||||||
const siteConfig = require(process.cwd() + "/siteConfig.js");
|
const translate = require('../../server/translate.js').translate;
|
||||||
const translate = require("../../server/translate.js").translate;
|
|
||||||
|
|
||||||
class AboutSlash extends React.Component {
|
class AboutSlash extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="pageContainer">
|
<div className="pageContainer">
|
||||||
<Container className="mainContainer documentContainer postContainer">
|
<Container className="mainContainer documentContainer postContainer">
|
||||||
<h1><translate>About Slash</translate></h1>
|
<h1>
|
||||||
<img src={`${siteConfig.baseUrl}img/docusaurus.svg`} alt="Docusaurus"/>
|
<translate>About Slash</translate>
|
||||||
|
</h1>
|
||||||
|
<img
|
||||||
|
src={`${siteConfig.baseUrl}img/docusaurus.svg`}
|
||||||
|
alt="Docusaurus"
|
||||||
|
/>
|
||||||
<p>
|
<p>
|
||||||
Slash is the official mascot of Docusaurus. You will find different variations of her throughout the <a href="https://docusaurus.io">website</a>, whether she is moving fast on her scooter or writing documentation at her standing desk. At Facebook, we have actual Slash plushies -- and you never know, you may see these plushies at various events and conferences in the future.
|
Slash is the official mascot of Docusaurus. You will find different
|
||||||
|
variations of her throughout the{' '}
|
||||||
|
<a href="https://docusaurus.io">website</a>, whether she is moving
|
||||||
|
fast on her scooter or writing documentation at her standing desk.
|
||||||
|
At Facebook, we have actual Slash plushies -- and you never know,
|
||||||
|
you may see these plushies at various events and conferences in the
|
||||||
|
future.
|
||||||
</p>
|
</p>
|
||||||
</Container>
|
</Container>
|
||||||
<Container className="mainContainer">
|
<Container className="mainContainer">
|
||||||
<h2><translate>Birth of Slash</translate></h2>
|
<h2>
|
||||||
<img src={`${siteConfig.baseUrl}img/slash-birth.png`} alt="Birth of Slash"/>
|
<translate>Birth of Slash</translate>
|
||||||
|
</h2>
|
||||||
|
<img
|
||||||
|
src={`${siteConfig.baseUrl}img/slash-birth.png`}
|
||||||
|
alt="Birth of Slash"
|
||||||
|
/>
|
||||||
<p>
|
<p>
|
||||||
The team sat in a conference room trying to come up with a name for the project. Dinosaurs became a theme, finally landing on Docusaurus, combining documentation with those many dinosaurs that end in "saurus". Of course, we needed a logo for our new project. Eric sat down and designed a logo that was quite beyond the norm of our normal open source project logos, but yet was just so awesome, we had to use it. We needed a name for this cute Docusaur. "Marky" for markdown? "Docky" for documentation? No, "Slash" for the normal way someone starts code documentation in many programming languages <code>//</code> or <code>/*</code> or <code>///</code>. And Slash was born.
|
The team sat in a conference room trying to come up with a name for
|
||||||
|
the project. Dinosaurs became a theme, finally landing on
|
||||||
|
Docusaurus, combining documentation with those many dinosaurs that
|
||||||
|
end in "saurus". Of course, we needed a logo for our new project.
|
||||||
|
Eric sat down and designed a logo that was quite beyond the norm of
|
||||||
|
our normal open source project logos, but yet was just so awesome,
|
||||||
|
we had to use it. We needed a name for this cute Docusaur. "Marky"
|
||||||
|
for markdown? "Docky" for documentation? No, "Slash" for the normal
|
||||||
|
way someone starts code documentation in many programming languages{' '}
|
||||||
|
<code>//</code> or <code>/*</code> or <code>///</code>. And Slash
|
||||||
|
was born.
|
||||||
</p>
|
</p>
|
||||||
</Container>
|
</Container>
|
||||||
<br />
|
<br />
|
||||||
|
@ -37,7 +64,7 @@ class AboutSlash extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
AboutSlash.defaultProps = {
|
AboutSlash.defaultProps = {
|
||||||
language: "en"
|
language: 'en',
|
||||||
};
|
};
|
||||||
|
|
||||||
AboutSlash.title = 'About Slash';
|
AboutSlash.title = 'About Slash';
|
||||||
|
|
|
@ -9,7 +9,6 @@ const React = require('react');
|
||||||
const CompLibrary = require('../../core/CompLibrary.js');
|
const CompLibrary = require('../../core/CompLibrary.js');
|
||||||
const Container = CompLibrary.Container;
|
const Container = CompLibrary.Container;
|
||||||
const GridBlock = CompLibrary.GridBlock;
|
const GridBlock = CompLibrary.GridBlock;
|
||||||
const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */
|
|
||||||
const siteConfig = require(process.cwd() + '/siteConfig.js');
|
const siteConfig = require(process.cwd() + '/siteConfig.js');
|
||||||
const translate = require('../../server/translate.js').translate;
|
const translate = require('../../server/translate.js').translate;
|
||||||
|
|
||||||
|
@ -74,17 +73,11 @@ class HomeSplash extends React.Component {
|
||||||
class Index extends React.Component {
|
class Index extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let language = this.props.language || 'en';
|
let language = this.props.language || 'en';
|
||||||
const showcase = siteConfig.users
|
const showcase = siteConfig.users.filter(user => user.pinned).map(user => (
|
||||||
.filter(user => {
|
<a href={user.infoLink} key={user.infoLink}>
|
||||||
return user.pinned;
|
|
||||||
})
|
|
||||||
.map((user, i) => {
|
|
||||||
return (
|
|
||||||
<a href={user.infoLink} key={i}>
|
|
||||||
<img src={user.image} alt={user.caption} title={user.caption} />
|
<img src={user.image} alt={user.caption} title={user.caption} />
|
||||||
</a>
|
</a>
|
||||||
);
|
));
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -12,9 +12,9 @@ const siteConfig = require(process.cwd() + '/siteConfig.js');
|
||||||
const translate = require('../../server/translate.js').translate;
|
const translate = require('../../server/translate.js').translate;
|
||||||
|
|
||||||
class Users extends React.Component {
|
class Users extends React.Component {
|
||||||
renderUser(user, i) {
|
renderUser(user) {
|
||||||
return (
|
return (
|
||||||
<a href={user.infoLink} key={i}>
|
<a href={user.infoLink} key={user.infoLink}>
|
||||||
<img src={user.image} alt={user.caption} title={user.caption} />
|
<img src={user.image} alt={user.caption} title={user.caption} />
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,6 +4,7 @@ window.addEventListener('load', function() {
|
||||||
function button(label, ariaLabel, icon, className) {
|
function button(label, ariaLabel, icon, className) {
|
||||||
const btn = document.createElement('button');
|
const btn = document.createElement('button');
|
||||||
btn.classList.add('btnIcon', className);
|
btn.classList.add('btnIcon', className);
|
||||||
|
btn.setAttribute('type', 'button');
|
||||||
btn.setAttribute('aria-label', ariaLabel);
|
btn.setAttribute('aria-label', ariaLabel);
|
||||||
btn.innerHTML =
|
btn.innerHTML =
|
||||||
'<div class="btnIcon__body">' +
|
'<div class="btnIcon__body">' +
|
||||||
|
@ -11,8 +12,7 @@ window.addEventListener('load', function() {
|
||||||
'<strong class="btnIcon__label">' +
|
'<strong class="btnIcon__label">' +
|
||||||
label +
|
label +
|
||||||
'</strong>' +
|
'</strong>' +
|
||||||
'</div>' +
|
'</div>';
|
||||||
'</button>';
|
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue