mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-28 00:17:14 +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
|
@ -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
|
||||
|
|
|
@ -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,32 +46,21 @@ 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'
|
||||
}
|
||||
alt={post.author}
|
||||
/>
|
||||
<img src={authorImageURL} 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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 = (
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -48,37 +48,33 @@ class GridBlock extends React.Component {
|
|||
}
|
||||
|
||||
renderBlockImage(image, imageLink, imageAlt) {
|
||||
if (image) {
|
||||
if (imageLink) {
|
||||
return (
|
||||
<div className="blockImage">
|
||||
<a href={imageLink}>
|
||||
<img src={image} alt={imageAlt} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="blockImage">
|
||||
<img src={image} alt={imageAlt} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (!image) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="blockImage">
|
||||
{imageLink ? (
|
||||
<a href={imageLink}>
|
||||
<img src={image} alt={imageAlt} />
|
||||
</a>
|
||||
) : (
|
||||
<img src={image} alt={imageAlt} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderBlockTitle(title) {
|
||||
if (title) {
|
||||
return (
|
||||
<h2>
|
||||
<MarkdownBlock>{title}</MarkdownBlock>
|
||||
</h2>
|
||||
);
|
||||
} else {
|
||||
if (!title) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<h2>
|
||||
<MarkdownBlock>{title}</MarkdownBlock>
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
return (
|
||||
<html>
|
||||
<html lang="en">
|
||||
<Head
|
||||
config={this.props.config}
|
||||
description={description}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return React.Children.map(this.props.children, child => {
|
||||
if (typeof child === 'string') {
|
||||
return (
|
||||
<span dangerouslySetInnerHTML={{__html: renderMarkdown(child)}} />
|
||||
);
|
||||
}
|
||||
|
||||
return child;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
var Container = this.props.container;
|
||||
|
||||
const Container = this.props.container;
|
||||
return <Container>{this.content()}</Container>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -11,7 +11,7 @@ const getTOC = require('../getTOC');
|
|||
|
||||
const mdContents = readFileSync(
|
||||
path.join(__dirname, '__fixtures__', 'getTOC.md'),
|
||||
'utf-8'
|
||||
'utf8'
|
||||
);
|
||||
|
||||
test('with defaults', () => {
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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) {
|
||||
return null;
|
||||
}
|
||||
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 = {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue