ESLintify Part 1 (#837)

* ESLint-ify

* Allow empty try/catch

* Escape regexp
This commit is contained in:
Yangshun Tay 2018-07-08 09:13:18 -07:00 committed by GitHub
parent 128dbfca0a
commit e8e3f42685
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 466 additions and 555 deletions

View file

@ -16,53 +16,23 @@ module.exports = {
'no-console': OFF,
// require radix argument in parseInt
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.
'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/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
'import/order': OFF, // 10
'arrow-body-style': OFF, // 10
camelcase: OFF, // 10
'react/jsx-curly-brace-presence': OFF, // 11
'react/no-unescaped-entities': OFF, // 12
'no-param-reassign': OFF, // 12
'no-unused-vars': OFF, // 13
'spaced-comment': OFF, // 14
'import/no-unresolved': OFF, // 15
'react/no-danger': OFF, // 16
'object-shorthand': OFF, // 16
'dot-notation': OFF, // 19
'react/prefer-stateless-function': OFF, // 22

View file

@ -72,7 +72,7 @@ class Footer extends React.Component {
href={this.props.config.repoUrl}
data-icon="octicon-star"
data-count-href="/facebook/docusaurus/stargazers"
data-show-count={true}
data-show-count="true"
data-count-aria-label="# stargazers on GitHub"
aria-label="Star this project on GitHub">
Star

View file

@ -52,11 +52,11 @@ const SplashContainer = props => (
const Logo = props => (
<div className="projectLogo">
<img src={props.img_src} />
<img src={props.img_src} alt="Project Logo" />
</div>
);
const ProjectTitle = props => (
const ProjectTitle = () => (
<h2 className="projectTitle">
{siteConfig.title}
<small>{siteConfig.tagline}</small>
@ -99,7 +99,7 @@ const Block = props => (
</Container>
);
const Features = props => (
const Features = () => (
<Block layout="fourColumn">
{[
{
@ -118,7 +118,7 @@ const Features = props => (
</Block>
);
const FeatureCallout = props => (
const FeatureCallout = () => (
<div
className="productShowcaseSection paddingBottom"
style={{textAlign: 'center'}}>
@ -127,7 +127,7 @@ const FeatureCallout = props => (
</div>
);
const LearnHow = props => (
const LearnHow = () => (
<Block background="light">
{[
{
@ -140,7 +140,7 @@ const LearnHow = props => (
</Block>
);
const TryOut = props => (
const TryOut = () => (
<Block id="try">
{[
{
@ -153,7 +153,7 @@ const TryOut = props => (
</Block>
);
const Description = props => (
const Description = () => (
<Block background="dark">
{[
{
@ -170,21 +170,16 @@ const Showcase = props => {
if ((siteConfig.users || []).length === 0) {
return null;
}
const showcase = siteConfig.users
.filter(user => {
return user.pinned;
})
.map((user, i) => {
return (
<a href={user.infoLink} key={i}>
const showcase = siteConfig.users.filter(user => user.pinned).map(user => (
<a href={user.infoLink} key={user.infoLink}>
<img src={user.image} alt={user.caption} title={user.caption} />
</a>
);
});
));
return (
<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>
<div className="logos">{showcase}</div>
<div className="more-users">

View file

@ -17,14 +17,13 @@ class Users extends React.Component {
if ((siteConfig.users || []).length === 0) {
return null;
}
const editUrl = siteConfig.repoUrl + '/edit/master/website/siteConfig.js';
const showcase = siteConfig.users.map((user, i) => {
return (
<a href={user.infoLink} key={i}>
const showcase = siteConfig.users.map(user => (
<a href={user.infoLink} key={user.infoLink}>
<img src={user.image} alt={user.caption} title={user.caption} />
</a>
);
});
));
return (
<div className="mainContainer">

View file

@ -52,7 +52,6 @@ beforeAll(() => {
inputAssetsFiles,
outputAssetsFiles,
] = results;
return;
});
});

View file

@ -5,11 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
const React = require('react');
const BlogPost = require('./BlogPost.js');
const BlogSidebar = require('./BlogSidebar.js');
const Container = require('./Container.js');
const MetadataBlog = require('./MetadataBlog.js');
const React = require('react');
const Site = require('./Site.js');
const utils = require('./utils.js');
@ -46,7 +46,7 @@ class BlogPageLayout extends React.Component {
<BlogPost
post={post}
content={post.content}
truncate={true}
truncate
key={
utils.getPath(post.path, this.props.config.cleanUrl) +
post.title

View file

@ -5,9 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/
const MarkdownBlock = require('./MarkdownBlock.js');
const React = require('react');
const MarkdownBlock = require('./MarkdownBlock.js');
const utils = require('./utils.js');
// inner blog component for the article itself, without sidebar/header/footer
@ -46,33 +46,22 @@ class BlogPost extends React.Component {
const className =
'authorPhoto' +
(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 (
<div className={className}>
<a href={post.authorURL} target="_blank" rel="noreferrer noopener">
<img
src={
'https://graph.facebook.com/' +
post.authorFBID +
'/picture/?height=200&width=200'
<img src={authorImageURL} alt={post.author} />
</a>
</div>
);
}
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;
}
}
renderTitle() {
const post = this.props.post;

View file

@ -5,19 +5,31 @@
* LICENSE file in the root directory of this source tree.
*/
const classNames = require('classnames');
const React = require('react');
const BlogPost = require('./BlogPost.js');
const BlogSidebar = require('./BlogSidebar.js');
const Container = require('./Container.js');
const Site = require('./Site.js');
const OnPageNav = require('./nav/OnPageNav.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
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() {
let post = this.props.metadata;
const post = this.props.metadata;
post.path = utils.getPath(post.path, this.props.config.cleanUrl);
const fbComment = this.props.config.facebookAppId &&
@ -72,8 +84,9 @@ class BlogPostLayout extends React.Component {
}
data-related={this.props.config.twitter}
data-via={post.authorTwitter}
data-show-count="false"
/>
data-show-count="false">
Tweet
</a>
</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() {
const hasOnPageNav = this.props.config.onPageNav === 'separate';
const post = this.props.metadata;

View file

@ -17,7 +17,7 @@ class BlogSidebar extends React.Component {
let blogSidebarTitleConfig = this.props.config.blogSidebarTitle || {};
let blogSidebarTitle = blogSidebarTitleConfig.default || 'Recent Posts';
if (this.props.config.blogSidebarCount) {
if (this.props.config.blogSidebarCount == 'ALL') {
if (this.props.config.blogSidebarCount === 'ALL') {
blogSidebarCount = MetadataBlog.length;
blogSidebarTitle = blogSidebarTitleConfig.all || 'All Blog Posts';
} else {

View file

@ -43,7 +43,7 @@ class Doc extends React.Component {
// If internationalization is enabled, show Recruiting link instead of Edit Link.
if (
this.props.language &&
this.props.language != 'en' &&
this.props.language !== 'en' &&
this.props.config.translationRecruitingLink
) {
editLink = (

View file

@ -5,16 +5,17 @@
* LICENSE file in the root directory of this source tree.
*/
const classNames = require('classnames');
const path = require('path');
const React = require('react');
const url = require('url');
const Container = require('./Container.js');
const Doc = require('./Doc.js');
const DocsSidebar = require('./DocsSidebar.js');
const OnPageNav = require('./nav/OnPageNav.js');
const Site = require('./Site.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
class DocsLayout extends React.Component {

View file

@ -48,37 +48,33 @@ class GridBlock extends React.Component {
}
renderBlockImage(image, imageLink, imageAlt) {
if (image) {
if (imageLink) {
if (!image) {
return null;
}
return (
<div className="blockImage">
{imageLink ? (
<a href={imageLink}>
<img src={image} alt={imageAlt} />
</a>
</div>
);
} else {
return (
<div className="blockImage">
) : (
<img src={image} alt={imageAlt} />
)}
</div>
);
}
} else {
return null;
}
}
renderBlockTitle(title) {
if (title) {
if (!title) {
return null;
}
return (
<h2>
<MarkdownBlock>{title}</MarkdownBlock>
</h2>
);
} else {
return null;
}
}
render() {

View file

@ -11,10 +11,7 @@ const React = require('react');
class Head extends React.Component {
render() {
const links = this.props.config.headerLinks;
let hasBlog = false;
links.map(link => {
if (link.blog) hasBlog = true;
});
const hasBlog = links.some(link => link.blog);
let highlight = {
version: '9.12.0',
@ -137,21 +134,13 @@ class Head extends React.Component {
{/* External resources */}
{this.props.config.stylesheets &&
this.props.config.stylesheets.map(function(source, idx) {
return (
<link rel="stylesheet" key={'stylesheet' + idx} href={source} />
);
})}
this.props.config.stylesheets.map(source => (
<link rel="stylesheet" key={source} href={source} />
))}
{this.props.config.scripts &&
this.props.config.scripts.map(function(source, idx) {
return (
<script
type="text/javascript"
key={'script' + idx}
src={source}
/>
);
})}
this.props.config.scripts.map(source => (
<script type="text/javascript" key={source} src={source} />
))}
{this.props.config.scrollToTop && (
<script

View file

@ -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;

View file

@ -29,7 +29,7 @@ class Redirect extends React.Component {
const redirect = this.props.redirect || false;
return (
<html>
<html lang="en">
<Head
config={this.props.config}
description={description}

View file

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const React = require('react');
const renderMarkdown = require('./renderMarkdown.js');
@ -20,22 +18,21 @@ class Remarkable extends React.Component {
}}
/>
);
} else {
}
return React.Children.map(this.props.children, child => {
if (typeof child === 'string') {
return (
<span dangerouslySetInnerHTML={{__html: renderMarkdown(child)}} />
);
} else {
}
return child;
}
});
}
}
render() {
var Container = this.props.container;
const Container = this.props.container;
return <Container>{this.content()}</Container>;
}
}

View file

@ -39,14 +39,8 @@ class Site extends React.Component {
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 (
<html {...htmlElementProps}>
<html lang={this.props.language}>
<Head
config={this.props.config}
description={description}

View file

@ -5,8 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
const anchors = require('../anchors');
const rules = require('remarkable/lib/rules');
const anchors = require('../anchors');
const md = {
renderer: {

View file

@ -11,7 +11,7 @@ const getTOC = require('../getTOC');
const mdContents = readFileSync(
path.join(__dirname, '__fixtures__', 'getTOC.md'),
'utf-8'
'utf8'
);
test('with defaults', () => {

View file

@ -6,17 +6,17 @@
*/
const path = require('path');
const fs = require('fs');
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'),
'utf-8'
'utf8'
);
const blogPostWithoutTruncateContents = readFileSync(
const blogPostWithoutTruncateContents = fs.readFileSync(
path.join(__dirname, '__fixtures__', 'blog-post-without-truncate.md'),
'utf-8'
'utf8'
);
describe('utils', () => {

View file

@ -52,8 +52,8 @@ module.exports = (content, headingTags = 'h2', subHeadingTags = 'h3') => {
if (headingLevels.includes(heading.lvl)) {
toc.push(entry);
current = entry;
} else {
current && current.children.push(entry);
} else if (current) {
current.children.push(entry);
}
});

View file

@ -89,6 +89,7 @@ class LanguageDropDown extends React.Component {
<img
className="languages-icon"
src={this.props.baseUrl + 'img/language.svg'}
alt="Languages icon"
/>
{currentLanguage}
</a>
@ -120,12 +121,6 @@ class LanguageDropDown extends React.Component {
// header navbar used by all pages generated with docusaurus
class HeaderNav extends React.Component {
constructor() {
super();
this.state = {
slideoutActive: false,
};
}
// function to generate each header link, used with each object in siteConfig.headerLinks
makeLinks(link) {
let href;
@ -143,7 +138,8 @@ class HeaderNav extends React.Component {
/>
</li>
);
} else if (link.languages) {
}
if (link.languages) {
if (
env.translation.enabled &&
env.translation.enabledLanguages().length > 1
@ -157,10 +153,10 @@ class HeaderNav extends React.Component {
key="languagedropdown"
/>
);
} else {
}
return null;
}
} else if (link.doc) {
if (link.doc) {
// set link to document with current page's language/version
const langPart = env.translation.enabled
? (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() {
const headerLinks = this.props.config.headerLinks;
// add language drop down to end if location not specified
@ -336,6 +291,47 @@ class HeaderNav extends React.Component {
</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 = {

View file

@ -23,8 +23,8 @@ const Headings = ({headings}) => {
if (!headings.length) return null;
return (
<ul className="toc-headings">
{headings.map((heading, i) => (
<li key={i}>
{headings.map(heading => (
<li key={heading.hashLink}>
<Link hashLink={heading.hashLink} content={heading.content} />
<Headings headings={heading.children} />
</li>

View file

@ -13,6 +13,77 @@ const translation = require('../../server/translation.js');
const utils = require('../utils.js');
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() {
return (
<nav className="toc">
@ -70,77 +141,6 @@ class SideNav extends React.Component {
</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 = {

View file

@ -42,17 +42,23 @@ class MarkdownRenderer {
// every single language (https://github.com/PrismJS/prism/issues/593)
require('prismjs/components/prism-' + language + '.min');
return prismjs.highlight(str, prismjs.languages[language]);
} catch (err) {}
} catch (err) {
console.error(err);
}
}
if (hljs.getLanguage(lang)) {
return hljs.highlight(lang, str).value;
}
} catch (err) {}
} catch (err) {
console.error(err);
}
}
try {
return hljs.highlightAuto(str).value;
} catch (err) {}
} catch (err) {
console.error(err);
}
return '';
},
@ -70,11 +76,11 @@ class MarkdownRenderer {
});
}
this._md = md;
this.md = md;
}
toHtml(source) {
const html = this._md.render(source);
const html = this.md.render(source);
// Ensure fenced code blocks use Highlight.js hljs class
// https://github.com/jonschlinkert/remarkable/issues/224

View file

@ -26,12 +26,11 @@ function removeExtension(path) {
function getPath(path, cleanUrl = false) {
if (cleanUrl) {
if (path.endsWith('/index.html')) {
return path.replace(/\/index.html$/, '');
} else {
return removeExtension(path);
}
return path.endsWith('/index.html')
? path.replace(/\/index.html$/, '')
: removeExtension(path);
}
return path;
}

View file

@ -111,8 +111,7 @@ if (defaultBranch !== DEPLOYMENT_BRANCH) {
shell.echo(`Error: Git checkout ${DEPLOYMENT_BRANCH} failed`);
shell.exit(1);
}
} else {
if (
} else if (
shell.exec(`git checkout -b ${DEPLOYMENT_BRANCH}`).code +
shell.exec(`git branch --set-upstream-to=origin/${DEPLOYMENT_BRANCH}`)
.code !==
@ -122,7 +121,6 @@ if (defaultBranch !== DEPLOYMENT_BRANCH) {
shell.exit(1);
}
}
}
shell.exec('git rm -rf .');
@ -140,7 +138,7 @@ const excludePath = `${PROJECT_NAME}-${DEPLOYMENT_BRANCH}`;
fs.copy(
fromPath,
toPath,
(src, dest) => {
src => {
if (src.indexOf('.DS_Store') !== -1) {
return false;
}

View file

@ -8,18 +8,16 @@
*/
const chalk = require('chalk');
const program = require('commander');
const escapeStringRegexp = require('escape-string-regexp');
const fs = require('fs');
const glob = require('glob');
const path = require('path');
const metadataUtils = require('./server/metadataUtils.js');
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
function makeHeader(metadata) {
let header = '---\n';
@ -30,9 +28,8 @@ function makeHeader(metadata) {
return header;
}
let currentVersion, newVersion;
const program = require('commander');
let currentVersion;
let newVersion;
program
.arguments('<version_name> <new_version_name>')
@ -123,7 +120,7 @@ if (fs.existsSync(currentSidebarFile)) {
fs.renameSync(currentSidebarFile, newSidebarFile);
let sidebarContent = fs.readFileSync(newSidebarFile, 'utf8');
sidebarContent = sidebarContent.replace(
new RegExp(`version-${RegExp.escape(currentVersion)}-`, 'g'),
new RegExp(`version-${escapeStringRegexp(currentVersion)}-`, 'g'),
`version-${newVersion}-`
);
fs.writeFileSync(newSidebarFile, sidebarContent);

View file

@ -13,9 +13,9 @@ const siteConfig = require(CWD + '/siteConfig.js');
const join = path.join;
const languages_js = join(CWD, 'languages.js');
const versions_json = join(CWD, 'versions.json');
const versions_js = join(CWD, 'pages/en/versions.js');
const languagesFile = join(CWD, 'languages.js');
const versionsJSONFile = join(CWD, 'versions.json');
const versionsFile = join(CWD, 'pages/en/versions.js');
class Translation {
constructor() {
@ -28,17 +28,15 @@ class Translation {
},
];
this._load();
this.load();
}
enabledLanguages() {
return this.languages.filter(lang => lang.enabled);
}
enabledLanguages = () => this.languages.filter(lang => lang.enabled);
_load() {
if (fs.existsSync(languages_js)) {
load() {
if (fs.existsSync(languagesFile)) {
this.enabled = true;
this.languages = require(languages_js);
this.languages = require(languagesFile);
}
}
}
@ -50,7 +48,7 @@ class Versioning {
this.versions = [];
this.missingVersionsPage = false;
this._load();
this.load();
}
printMissingVersionsPageError() {
@ -61,16 +59,16 @@ class Versioning {
);
}
_load() {
if (fs.existsSync(versions_json)) {
load() {
if (fs.existsSync(versionsJSONFile)) {
this.enabled = true;
this.versions = JSON.parse(fs.readFileSync(versions_json, 'utf8'));
this.versions = JSON.parse(fs.readFileSync(versionsJSONFile, 'utf8'));
this.defaultVersion = siteConfig.defaultVersionShown
? siteConfig.defaultVersionShown
: this.versions[0]; // otherwise show the latest version (other than next/master)
}
if (!fs.existsSync(versions_js)) {
if (!fs.existsSync(versionsFile)) {
this.missingVersionsPage = true;
}
}

View file

@ -137,13 +137,11 @@ async function execute() {
} else {
file = join(CWD, 'versioned_docs', metadata.source);
}
} else {
if (metadata.language === 'en') {
} else if (metadata.language === 'en') {
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
} else {
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
}
}
if (!fs.existsSync(file)) {
return;
@ -156,14 +154,14 @@ async function execute() {
const language = metadata.language;
// 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);
}
let defaultVersion = env.versioning.defaultVersion;
// 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];
link = utils.getPath(link, siteConfig.cleanUrl);
link = link.replace('/en/', '/' + language + '/');
@ -489,18 +487,16 @@ async function execute() {
const match = regexLang.exec(normalizedFile);
const langParts = match[1].split(sep);
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++) {
let language = enabledLanguages[i];
// skip conversion from english file if a file exists for this language
const language = enabledLanguages[i];
// Skip conversion from English file if a file exists for this language.
if (
language !== 'en' &&
fs.existsSync(
language === 'en' ||
!fs.existsSync(
normalizedFile.replace(sep + 'en' + sep, sep + language + sep)
)
) {
continue;
}
translate.setLanguage(language);
const str = renderToStaticMarkupWithDoctype(
<Site
@ -518,6 +514,7 @@ async function execute() {
str
);
}
}
// write to base level
let language = env.translation.enabled ? 'en' : '';

View file

@ -55,7 +55,9 @@ function extractMetadata(content) {
.trim();
try {
value = JSON.parse(value);
} catch (e) {}
} catch (err) {
// Ignore the error as it means it's not a JSON value.
}
metadata[key] = value;
}
return {metadata, rawContent: both.content};

View file

@ -5,10 +5,11 @@
* 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 fs = require('fs');
const CWD = process.cwd();
let languages;
if (fs.existsSync(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
function readCategories(sidebar) {
const enabledLanguages = [];
languages.filter(lang => lang.enabled).map(lang => {
enabledLanguages.push(lang.tag);
});
const enabledLanguages = languages
.filter(lang => lang.enabled)
.map(lang => lang.tag);
const allCategories = {};
@ -88,7 +88,9 @@ function readCategories(sidebar) {
let i = 0;
while (metadata && i++ < 1000) {
if (!currentCategory || metadata.category !== currentCategory.name) {
currentCategory && categories.push(currentCategory);
if (currentCategory) {
categories.push(currentCategory);
}
currentCategory = {
name: metadata.category,
links: [],

View file

@ -66,7 +66,8 @@ function readSidebar() {
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
let previous, next;
let previous;
let next;
if (i > 0) previous = ids[i - 1];
if (i < ids.length - 1) next = ids[i + 1];
order[id] = {
@ -86,13 +87,13 @@ function processMetadata(file, refDir) {
const language = utils.getLanguage(file, refDir) || 'en';
const metadata = {};
for (const fieldName of Object.keys(result.metadata)) {
Object.keys(result.metadata).forEach(fieldName => {
if (SupportedHeaderFields.has(fieldName)) {
metadata[fieldName] = result.metadata[fieldName];
} else {
console.warn(`Header field "${fieldName}" in ${file} is not supported.`);
}
}
});
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
// these will get replaced if/when the localized file is downloaded from crowdin
enabledLanguages
.filter(currentLanguage => {
return currentLanguage != 'en';
})
.map(currentLanguage => {
.filter(currentLanguage => currentLanguage !== 'en')
.forEach(currentLanguage => {
let baseMetadata = Object.assign({}, metadata);
baseMetadata['id'] = baseMetadata['id']
.toString()
@ -291,7 +290,7 @@ function generateMetadataDocs() {
});
fs.writeFileSync(
__dirname + '/../core/metadata.js',
path.join(__dirname, '/../core/metadata.js'),
'/**\n' +
' * @' +
'generated\n' + // separate this out for Nuclide treating @generated as readonly
@ -360,7 +359,7 @@ function generateMetadataBlog() {
);
fs.writeFileSync(
__dirname + '/../core/MetadataBlog.js',
path.join(__dirname, '/../core/MetadataBlog.js'),
'/**\n' +
' * @' +
'generated\n' + // separate this out for Nuclide treating @generated as readonly

View file

@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable no-cond-assign */
function execute(port, options) {
const extractTranslations = require('../write-translations');
@ -45,8 +47,18 @@ function execute(port, options) {
const join = path.join;
const sep = path.sep;
// remove a module and child modules from require cache, so server does not have
// to be restarted
function removeModulePathFromCache(moduleName) {
/* 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) {
let mod = require.resolve(moduleName);
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');
@ -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();
@ -200,13 +234,11 @@ function execute(port, options) {
} else {
file = join(CWD, 'versioned_docs', metadata.source);
}
} else {
if (!env.translation.enabled || metadata.language === 'en') {
} else if (!env.translation.enabled || metadata.language === 'en') {
file = join(CWD, '..', readMetadata.getDocsPath(), metadata.source);
} else {
file = join(CWD, 'translated_docs', metadata.language, metadata.source);
}
}
if (!fs.existsSync(file)) {
next();
@ -225,7 +257,7 @@ function execute(port, options) {
let defaultVersion = env.versioning.defaultVersion;
// 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];
link = utils.getPath(link, siteConfig.cleanUrl);
link = link.replace('/en/', '/' + language + '/');
@ -333,8 +365,8 @@ function execute(port, options) {
);
const str = renderToStaticMarkupWithDoctype(blogPageComp);
let path = (page > 0 ? 'page' + (page + 1) : '') + '/index.html';
blogPages[path] = str;
const pagePath = (page > 0 ? 'page' + (page + 1) : '') + '/index.html';
blogPages[pagePath] = str;
}
let parts = req.path.toString().split('blog/');
@ -398,7 +430,7 @@ function execute(port, options) {
// handle all other main pages
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, '');
htmlFile = join(CWD, 'pages', htmlFile);
if (
@ -470,8 +502,8 @@ function execute(port, options) {
fs.existsSync((userFile = englishFile))
) {
// copy into docusaurus so require paths work
let parts = userFile.split('pages' + sep);
let tempFile = join(__dirname, '..', 'pages', parts[1]);
let userFileParts = userFile.split('pages' + sep);
let tempFile = join(__dirname, '..', 'pages', userFileParts[1]);
tempFile = tempFile.replace(
path.basename(file),
'temp' + path.basename(file)
@ -501,7 +533,6 @@ function execute(port, options) {
res.send(str);
} else {
next();
return;
}
});
@ -598,36 +629,6 @@ function execute(port, options) {
if (options.watch) startLiveReload();
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;

View file

@ -32,8 +32,6 @@ MetadataBlog = require('../core/MetadataBlog.js');
module.exports = function(callback) {
console.log('sitemap.js triggered...');
let urls = [];
let files = glob.sync(CWD + '/pages/en/**/*.js');
// 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 (fs.existsSync(CWD + '/languages.js')) {
let languages = require(CWD + '/languages.js');
enabledLanguages = languages.filter(lang => {
return lang.enabled == true;
});
enabledLanguages = languages.filter(lang => lang.enabled);
}
// create a url mapping to all the enabled languages files
files.map(file => {
// Create a url mapping to all the enabled languages files
const urls = files.map(file => {
let url = file.split('/pages/en')[1];
url = siteConfig.cleanUrl
? url.replace(/\.js$/, '')
: url.replace(/\.js$/, '.html');
let links = enabledLanguages.map(lang => {
const links = enabledLanguages.map(lang => {
let langUrl = lang.tag + url;
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({
url: '/blog/' + utils.getPath(blog.path, siteConfig.cleanUrl),
changefreq: 'weekly',
@ -76,7 +72,7 @@ module.exports = function(callback) {
Object.keys(Metadata)
.filter(key => Metadata[key].language === 'en')
.map(key => {
.forEach(key => {
let doc = Metadata[key];
let docUrl = utils.getPath(doc.permalink, siteConfig.cleanUrl);
let links = enabledLanguages.map(lang => {
@ -94,7 +90,7 @@ module.exports = function(callback) {
const sm = sitemap.createSitemap({
hostname: siteConfig.url,
cacheTime: 600 * 1000, // 600 sec - cache purge period
urls: urls,
urls,
});
sm.toXML((err, xml) => {

View file

@ -25,8 +25,8 @@ module.exports = function translatePlugin(babel) {
description = attributes[i].value.value;
}
}
/* use an expression container if inside a jsxelement */
if (path.findParent(path => true).node.type === 'JSXElement') {
/* use an expression container if inside a JSXElement */
if (path.findParent(() => true).node.type === 'JSXElement') {
path.replaceWith(
t.jSXExpressionContainer(
t.callExpression(t.identifier('translate'), [

View file

@ -96,7 +96,7 @@ files.forEach(file => {
// returns the version to use for a document based on its id and
// what the requested version is
function docVersion(id, req_version) {
function docVersion(id, reqVersion) {
if (!available[id]) {
return null;
}
@ -104,13 +104,10 @@ function docVersion(id, req_version) {
// is found, then check if that version has an available file to use
let requestedFound = false;
for (let i = 0; i < versions.length; i++) {
if (versions[i] === req_version) {
if (versions[i] === reqVersion) {
requestedFound = true;
}
if (!requestedFound) {
continue;
}
if (available[id].has(versions[i])) {
if (requestedFound && available[id].has(versions[i])) {
return versions[i];
}
}
@ -243,18 +240,16 @@ function docData() {
}
// 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
// is found, then check if that version has an available file to use
let requestedFound = false;
for (let i = 0; i < versions.length; i++) {
if (versions[i] === req_version) {
if (versions[i] === reqVersion) {
requestedFound = true;
}
if (!requestedFound) {
continue;
}
if (
requestedFound &&
fs.existsSync(
CWD + '/versioned_sidebars/version-' + versions[i] + '-sidebars.json'
)
@ -263,7 +258,7 @@ function sidebarVersion(req_version) {
}
}
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.`
);
}

View file

@ -18,13 +18,12 @@ require('babel-register')({
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 fs = require('fs');
const program = require('commander');
const openBrowser = require('react-dev-utils/openBrowser');
const tcpPortUsed = require('tcp-port-used');
const CWD = process.cwd();
const env = require('./server/env.js');
@ -40,8 +39,6 @@ if (env.versioning.enabled && env.versioning.missingVersionsPage) {
process.exit(1);
}
const program = require('commander');
program
.option('--port <number>', 'Specify port number')
.option('--no-watch', 'Toggle live reload file watching')
@ -50,7 +47,6 @@ program
let port = parseInt(program.port, 10) || process.env.PORT || 3000;
let numAttempts = 0;
const MAX_ATTEMPTS = 10;
checkPort();
function checkPort() {
tcpPortUsed
@ -84,3 +80,5 @@ function checkPort() {
}, 0);
});
}
checkPort();

View file

@ -7,11 +7,13 @@
* LICENSE file in the root directory of this source tree.
*/
const program = require('commander');
const chalk = require('chalk');
const glob = require('glob');
const fs = require('fs-extra');
const path = require('path');
const mkdirp = require('mkdirp');
const chalk = require('chalk');
const path = require('path');
const readMetadata = require('./server/readMetadata.js');
const utils = require('./server/utils.js');
const versionFallback = require('./server/versionFallback.js');
@ -28,7 +30,6 @@ if (fs.existsSync(CWD + '/versions.json')) {
let version;
const program = require('commander');
program
.arguments('<version>')
.action(ver => {
@ -130,16 +131,18 @@ if (versionFallback.diffLatestSidebar()) {
const versioned = {};
Object.keys(sidebar).forEach(sb => {
const version_sb = 'version-' + version + '-' + sb;
versioned[version_sb] = {};
const versionSidebar = 'version-' + version + '-' + sb;
versioned[versionSidebar] = {};
const categories = sidebar[sb];
Object.keys(categories).forEach(category => {
versioned[version_sb][category] = [];
versioned[versionSidebar][category] = [];
const ids = categories[category];
ids.forEach((id, index) => {
versioned[version_sb][category].push('version-' + version + '-' + id);
ids.forEach(id => {
versioned[versionSidebar][category].push(
'version-' + version + '-' + id
);
});
});
});

View file

@ -9,15 +9,16 @@
/* 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 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');
let customTranslations = {
@ -46,10 +47,10 @@ function execute() {
};
// 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() + '/**');
files.forEach(file => {
const extension = path.extname(file);
const extension = nodePath.extname(file);
if (extension === '.md' || extension === '.markdown') {
let res;
try {
@ -115,7 +116,7 @@ function execute() {
// go through pages to look for text inside translate tags
files = glob.sync(CWD + '/pages/en/**');
files.forEach(file => {
const extension = path.extname(file);
const extension = nodePath.extname(file);
if (extension === '.js') {
const ast = babylon.parse(fs.readFileSync(file, 'utf8'), {
plugins: ['jsx'],

View file

@ -5,29 +5,56 @@
* LICENSE file in the root directory of this source tree.
*/
const React = require("react");
const CompLibrary = require("../../core/CompLibrary.js");
/* eslint-disable react/jsx-no-comment-textnodes */
const React = require('react');
const CompLibrary = require('../../core/CompLibrary.js');
const Container = CompLibrary.Container;
const GridBlock = CompLibrary.GridBlock;
const siteConfig = require(process.cwd() + "/siteConfig.js");
const translate = require("../../server/translate.js").translate;
const siteConfig = require(process.cwd() + '/siteConfig.js');
const translate = require('../../server/translate.js').translate;
class AboutSlash extends React.Component {
render() {
return (
<div className="pageContainer">
<Container className="mainContainer documentContainer postContainer">
<h1><translate>About Slash</translate></h1>
<img src={`${siteConfig.baseUrl}img/docusaurus.svg`} alt="Docusaurus"/>
<h1>
<translate>About Slash</translate>
</h1>
<img
src={`${siteConfig.baseUrl}img/docusaurus.svg`}
alt="Docusaurus"
/>
<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>
</Container>
<Container className="mainContainer">
<h2><translate>Birth of Slash</translate></h2>
<img src={`${siteConfig.baseUrl}img/slash-birth.png`} alt="Birth of Slash"/>
<h2>
<translate>Birth of Slash</translate>
</h2>
<img
src={`${siteConfig.baseUrl}img/slash-birth.png`}
alt="Birth of Slash"
/>
<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>
</Container>
<br />
@ -37,7 +64,7 @@ class AboutSlash extends React.Component {
}
AboutSlash.defaultProps = {
language: "en"
language: 'en',
};
AboutSlash.title = 'About Slash';

View file

@ -9,7 +9,6 @@ const React = require('react');
const CompLibrary = require('../../core/CompLibrary.js');
const Container = CompLibrary.Container;
const GridBlock = CompLibrary.GridBlock;
const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */
const siteConfig = require(process.cwd() + '/siteConfig.js');
const translate = require('../../server/translate.js').translate;
@ -74,17 +73,11 @@ class HomeSplash extends React.Component {
class Index extends React.Component {
render() {
let language = this.props.language || 'en';
const showcase = siteConfig.users
.filter(user => {
return user.pinned;
})
.map((user, i) => {
return (
<a href={user.infoLink} key={i}>
const showcase = siteConfig.users.filter(user => user.pinned).map(user => (
<a href={user.infoLink} key={user.infoLink}>
<img src={user.image} alt={user.caption} title={user.caption} />
</a>
);
});
));
return (
<div>

View file

@ -12,9 +12,9 @@ const siteConfig = require(process.cwd() + '/siteConfig.js');
const translate = require('../../server/translate.js').translate;
class Users extends React.Component {
renderUser(user, i) {
renderUser(user) {
return (
<a href={user.infoLink} key={i}>
<a href={user.infoLink} key={user.infoLink}>
<img src={user.image} alt={user.caption} title={user.caption} />
</a>
);

View file

@ -4,6 +4,7 @@ window.addEventListener('load', function() {
function button(label, ariaLabel, icon, className) {
const btn = document.createElement('button');
btn.classList.add('btnIcon', className);
btn.setAttribute('type', 'button');
btn.setAttribute('aria-label', ariaLabel);
btn.innerHTML =
'<div class="btnIcon__body">' +
@ -11,8 +12,7 @@ window.addEventListener('load', function() {
'<strong class="btnIcon__label">' +
label +
'</strong>' +
'</div>' +
'</button>';
'</div>';
return btn;
}