ff-stream-web

git clone git://archive.git.mtrnord.blog/MTRNord/ff-stream-web.git
Log | Files | Refs | README | LICENSE

commit ed5dfa9f4bf2a870092596eb26c760f6b8701df5
parent 02877714b77962cc72ea78489b89bdb4c0d468ff
Author: Vladimir Kutepov <frenzzy.man@gmail.com>
Date:   Fri, 10 Feb 2017 18:33:45 +0300

Reenable ESLint rules in accordance to Airbnb style guide (#1126)


Diffstat:
Mpackage.json | 9+--------
Msrc/components/Header/Header.js | 2+-
Msrc/components/Html.js | 32++++++++++++++++++++++++++------
Msrc/components/Link/Link.js | 6+++++-
Msrc/components/Navigation/Navigation.css | 3++-
Msrc/components/Navigation/Navigation.js | 8++------
Msrc/components/Page/Page.js | 9++++++---
Msrc/data/queries/news.js | 2+-
Msrc/routes/error/ErrorPage.js | 6+++++-
Msrc/routes/home/Home.css | 28+++++++++++++++++++---------
Msrc/routes/home/Home.js | 21++++++++++-----------
Msrc/server.js | 6++++--
Mtools/lib/fs.js | 6+++---
Mtools/run.js | 4++--
Mtools/runServer.js | 2+-
15 files changed, 88 insertions(+), 56 deletions(-)

diff --git a/package.json b/package.json @@ -162,17 +162,10 @@ "browser": true }, "rules": { - "arrow-parens": "off", - "generator-star-spacing": "off", "import/extensions": "off", "import/no-extraneous-dependencies": "off", - "react/forbid-prop-types": "off", "react/jsx-filename-extension": "off", - "react/no-array-index-key": "off", - "react/no-danger": "off", - "react/no-unused-prop-types": "off", - "react/prefer-stateless-function": "off", - "react/require-default-props": "off" + "react/prefer-stateless-function": "off" } }, "stylelint": { diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js @@ -20,7 +20,7 @@ class Header extends React.Component { return ( <div className={s.root}> <div className={s.container}> - <Navigation className={s.nav} /> + <Navigation /> <Link className={s.brand} to="/"> <img src={logoUrl} srcSet={`${logoUrl2x} 2x`} width="38" height="38" alt="React" /> <span className={s.brandTxt}>Your Company</span> diff --git a/src/components/Html.js b/src/components/Html.js @@ -14,13 +14,21 @@ class Html extends React.Component { static propTypes = { title: PropTypes.string.isRequired, description: PropTypes.string.isRequired, - style: PropTypes.string, + styles: PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.string.isRequired, + cssText: PropTypes.string.isRequired, + }).isRequired), scripts: PropTypes.arrayOf(PropTypes.string.isRequired), - children: PropTypes.string, + children: PropTypes.string.isRequired, + }; + + static defaultProps = { + styles: [], + scripts: [], }; render() { - const { title, description, style, scripts, children } = this.props; + const { title, description, styles, scripts, children } = this.props; return ( <html className="no-js" lang="en"> <head> @@ -30,13 +38,25 @@ class Html extends React.Component { <meta name="description" content={description} /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="apple-touch-icon" href="apple-touch-icon.png" /> - {style && <style id="css" dangerouslySetInnerHTML={{ __html: style }} />} + {styles.map(style => + <style + key={style.id} + id={style.id} + // eslint-disable-next-line react/no-danger + dangerouslySetInnerHTML={{ __html: style.cssText }} + />, + )} </head> <body> - <div id="app" dangerouslySetInnerHTML={{ __html: children }} /> - {scripts && scripts.map(script => <script key={script} src={script} />)} + <div + id="app" + // eslint-disable-next-line react/no-danger + dangerouslySetInnerHTML={{ __html: children }} + /> + {scripts.map(script => <script key={script} src={script} />)} {analytics.google.trackingId && <script + // eslint-disable-next-line react/no-danger dangerouslySetInnerHTML={{ __html: 'window.ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date;' + `ga('create','${analytics.google.trackingId}','auto');ga('send','pageview')` }} diff --git a/src/components/Link/Link.js b/src/components/Link/Link.js @@ -21,10 +21,14 @@ function isModifiedEvent(event) { class Link extends React.Component { static propTypes = { to: PropTypes.string.isRequired, - children: PropTypes.node, + children: PropTypes.node.isRequired, onClick: PropTypes.func, }; + static defaultProps = { + onClick: null, + }; + handleClick = (event) => { if (this.props.onClick) { this.props.onClick(event); diff --git a/src/components/Navigation/Navigation.css b/src/components/Navigation/Navigation.css @@ -8,7 +8,8 @@ */ .root { - margin: 0; + float: right; + margin: 6px 0 0; } .link { diff --git a/src/components/Navigation/Navigation.js b/src/components/Navigation/Navigation.js @@ -7,20 +7,16 @@ * LICENSE.txt file in the root directory of this source tree. */ -import React, { PropTypes } from 'react'; +import React from 'react'; import cx from 'classnames'; import withStyles from 'isomorphic-style-loader/lib/withStyles'; import s from './Navigation.css'; import Link from '../Link'; class Navigation extends React.Component { - static propTypes = { - className: PropTypes.string, - }; - render() { return ( - <div className={cx(s.root, this.props.className)} role="navigation"> + <div className={s.root} role="navigation"> <Link className={s.link} to="/about">About</Link> <Link className={s.link} to="/contact">Contact</Link> <span className={s.spacer}> | </span> diff --git a/src/components/Page/Page.js b/src/components/Page/Page.js @@ -13,7 +13,7 @@ import s from './Page.css'; class Page extends React.Component { static propTypes = { - title: PropTypes.string, + title: PropTypes.string.isRequired, html: PropTypes.string.isRequired, }; @@ -22,8 +22,11 @@ class Page extends React.Component { return ( <div className={s.root}> <div className={s.container}> - {title && <h1>{title}</h1>} - <div dangerouslySetInnerHTML={{ __html: html }} /> + <h1>{title}</h1> + <div + // eslint-disable-next-line react/no-danger + dangerouslySetInnerHTML={{ __html: html }} + /> </div> </div> ); diff --git a/src/data/queries/news.js b/src/data/queries/news.js @@ -30,7 +30,7 @@ const news = { lastFetchTime = new Date(); lastFetchTask = fetch(url) .then(response => response.json()) - .then(data => { + .then((data) => { if (data.status === 'ok') { items = data.items; } diff --git a/src/routes/error/ErrorPage.js b/src/routes/error/ErrorPage.js @@ -13,7 +13,11 @@ import s from './ErrorPage.css'; class ErrorPage extends React.Component { static propTypes = { - error: PropTypes.object.isRequired, + error: PropTypes.shape({ + name: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + stack: PropTypes.string.isRequired, + }).isRequired, }; render() { diff --git a/src/routes/home/Home.css b/src/routes/home/Home.css @@ -20,20 +20,30 @@ max-width: var(--max-content-width); } -.news { - padding: 0; -} - .newsItem { - list-style-type: none; - padding-bottom: 6px; + margin: 0 0 2rem; } .newsTitle { - font-size: 1.125em; + font-size: 1.5rem; } -.newsTitle, .newsDesc { - display: block; + h1, + h2, + h3, + h4, + h5, + h6 { + font-size: 1.125rem; + } + + pre { + white-space: pre-wrap; + font-size: 0.875rem; + } + + img { + max-width: 100%; + } } diff --git a/src/routes/home/Home.js b/src/routes/home/Home.js @@ -25,17 +25,16 @@ class Home extends React.Component { <div className={s.root}> <div className={s.container}> <h1>React.js News</h1> - <ul className={s.news}> - {this.props.news.map((item, index) => ( - <li key={index} className={s.newsItem}> - <a href={item.link} className={s.newsTitle}>{item.title}</a> - <span - className={s.newsDesc} - dangerouslySetInnerHTML={{ __html: item.content.substring(0, 100) }} - /> - </li> - ))} - </ul> + {this.props.news.map(item => ( + <article key={item.link} className={s.newsItem}> + <h1 className={s.newsTitle}><a href={item.link}>{item.title}</a></h1> + <div + className={s.newsDesc} + // eslint-disable-next-line react/no-danger + dangerouslySetInnerHTML={{ __html: item.content }} + /> + </article> + ))} </div> </div> ); diff --git a/src/server.js b/src/server.js @@ -112,7 +112,9 @@ app.get('*', async (req, res, next) => { const data = { ...route }; data.children = ReactDOM.renderToString(<App context={context}>{route.component}</App>); - data.style = [...css].join(''); + data.styles = [ + { id: 'css', cssText: [...css].join('') }, + ]; data.scripts = [ assets.vendor.js, assets.client.js, @@ -142,7 +144,7 @@ app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars <Html title="Internal Server Error" description={err.message} - style={errorPageStyle._getCss()} // eslint-disable-line no-underscore-dangle + styles={[{ id: 'css', cssText: errorPageStyle._getCss() }]} // eslint-disable-line no-underscore-dangle > {ReactDOM.renderToString(<ErrorPageWithoutStyle error={err} />)} </Html>, diff --git a/tools/lib/fs.js b/tools/lib/fs.js @@ -13,7 +13,7 @@ import glob from 'glob'; import mkdirp from 'mkdirp'; import rimraf from 'rimraf'; -export const readFile = (file) => new Promise((resolve, reject) => { +export const readFile = file => new Promise((resolve, reject) => { fs.readFile(file, 'utf8', (err, data) => (err ? reject(err) : resolve(data))); }); @@ -46,7 +46,7 @@ export const readDir = (pattern, options) => new Promise((resolve, reject) => glob(pattern, options, (err, result) => (err ? reject(err) : resolve(result))), ); -export const makeDir = (name) => new Promise((resolve, reject) => { +export const makeDir = name => new Promise((resolve, reject) => { mkdirp(name, err => (err ? reject(err) : resolve())); }); @@ -56,7 +56,7 @@ export const copyDir = async (source, target) => { nosort: true, dot: true, }); - await Promise.all(dirs.map(async dir => { + await Promise.all(dirs.map(async (dir) => { const from = path.resolve(source, dir); const to = path.resolve(target, dir); await makeDir(path.dirname(to)); diff --git a/tools/run.js b/tools/run.js @@ -17,7 +17,7 @@ function run(fn, options) { console.log( `[${format(start)}] Starting '${task.name}${options ? ` (${options})` : ''}'...`, ); - return task(options).then(resolution => { + return task(options).then((resolution) => { const end = new Date(); const time = end.getTime() - start.getTime(); console.log( @@ -30,7 +30,7 @@ function run(fn, options) { if (require.main === module && process.argv.length > 2) { delete require.cache[__filename]; // eslint-disable-line no-underscore-dangle const module = require(`./${process.argv[2]}.js`).default; // eslint-disable-line import/no-dynamic-require - run(module).catch(err => { console.error(err.stack); process.exit(1); }); + run(module).catch((err) => { console.error(err.stack); process.exit(1); }); } export default run; diff --git a/tools/runServer.js b/tools/runServer.js @@ -21,7 +21,7 @@ const serverPath = path.join(output.path, output.filename); // Launch or restart the Node.js server function runServer() { - return new Promise(resolve => { + return new Promise((resolve) => { function onStdOut(data) { const time = new Date().toTimeString(); const match = data.toString('utf8').match(RUNNING_REGEXP);