ff-stream-web

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

commit bacde22a52cf3e158ebc985433141123f5b0a3d7
parent 67813fbbb873df8b2c8005e1630c2036097e6d7e
Author: Konstantin Tarkus <hello@tarkus.me>
Date:   Sun, 10 May 2015 23:56:48 +0300

Remove global 'click' event handler in favor of Link.handleClick helper method

Diffstat:
Msrc/components/App/App.js | 53-----------------------------------------------------
Msrc/components/Footer/Footer.js | 5+++--
Msrc/components/Header/Header.js | 3++-
Msrc/components/Navigation/Navigation.js | 9+++++----
Asrc/utils/Link.js | 29+++++++++++++++++++++++++++++
5 files changed, 39 insertions(+), 60 deletions(-)

diff --git a/src/components/App/App.js b/src/components/App/App.js @@ -26,12 +26,10 @@ class App { componentDidMount() { window.addEventListener('popstate', this.handlePopState); - window.addEventListener('click', this.handleClick); } componentWillUnmount() { window.removeEventListener('popstate', this.handlePopState); - window.removeEventListener('click', this.handleClick); } shouldComponentUpdate(nextProps) { @@ -82,57 +80,6 @@ class App { AppActions.navigateTo(window.location.pathname, {replace: !!event.state}); } - handleClick(event) { - if (event.button === 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.defaultPrevented) { - return; - } - - // Ensure link - var el = event.target; - while (el && el.nodeName !== 'A') { - el = el.parentNode; - } - if (!el || el.nodeName !== 'A') { - return; - } - - // Ignore if tag has - // 1. "download" attribute - // 2. rel="external" attribute - if (el.getAttribute('download') || el.getAttribute('rel') === 'external') { - return; - } - - // Ensure non-hash for the same path - var link = el.getAttribute('href'); - if (el.pathname === location.pathname && (el.hash || link === '#')) { - return; - } - - // Check for mailto: in the href - if (link && link.indexOf('mailto:') > -1) { - return; - } - - // Check target - if (el.target) { - return; - } - - // X-origin - var origin = window.location.protocol + '//' + window.location.hostname + - (window.location.port ? ':' + window.location.port : ''); - if (!(el.href && el.href.indexOf(origin) === 0)) { - return; - } - - // Rebuild path - var path = el.pathname + el.search + (el.hash || ''); - - event.preventDefault(); - AppActions.navigateTo(path); - } - } export default App; diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js @@ -2,6 +2,7 @@ import React, { PropTypes } from 'react'; // eslint-disable-line no-unused-vars import './Footer.less'; +import Link from '../../utils/Link'; import Css from '../../utils/Css'; import setViewport from '../decorators/setViewport'; // eslint-disable-line no-unused-vars @@ -27,9 +28,9 @@ class Footer { <div className="Footer-container"> <span className="Footer-text">© Your Company</span> <span className="Footer-spacer">·</span> - <a className="Footer-link" href="/">Home</a> + <a className="Footer-link" href="/" onClick={Link.handleClick}>Home</a> <span className="Footer-spacer">·</span> - <a className="Footer-link" href="/privacy">Privacy</a> + <a className="Footer-link" href="/privacy" onClick={Link.handleClick}>Privacy</a> <span className="Footer-spacer"> | </span> <span ref="viewport" className="Footer-viewport Footer-text Footer-text--muted">Viewport:</span> </div> diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js @@ -2,6 +2,7 @@ import React from 'react'; // eslint-disable-line no-unused-vars import './Header.less'; +import Link from '../../utils/Link'; import Navigation from '../Navigation'; class Header { @@ -10,7 +11,7 @@ class Header { return ( <div className="Header"> <div className="Header-container"> - <a className="Header-brand" href="/"> + <a className="Header-brand" href="/" onClick={Link.handleClick}> <img className="Header-brandImg" src={require('./logo-small.png')} width="38" height="38" alt="React" /> <span className="Header-brandTxt">Your Company</span> </a> diff --git a/src/components/Navigation/Navigation.js b/src/components/Navigation/Navigation.js @@ -3,18 +3,19 @@ import React from 'react'; // eslint-disable-line no-unused-vars import cx from 'classnames'; import './Navigation.less'; +import Link from '../../utils/Link'; class Navigation { render() { return ( <div className={cx(this.props.className, 'Navigation')} role="navigation"> - <a className="Navigation-link" href="/about">About</a> - <a className="Navigation-link" href="/contact">Contact</a> + <a className="Navigation-link" href="/about" onClick={Link.handleClick}>About</a> + <a className="Navigation-link" href="/contact" onClick={Link.handleClick}>Contact</a> <span className="Navigation-spacer"> | </span> - <a className="Navigation-link" href="/login">Log in</a> + <a className="Navigation-link" href="/login" onClick={Link.handleClick}>Log in</a> <span className="Navigation-spacer">or</span> - <a className="Navigation-link Navigation-link--highlight" href="/register">Sign up</a> + <a className="Navigation-link Navigation-link--highlight" href="/register" onClick={Link.handleClick}>Sign up</a> </div> ); } diff --git a/src/utils/Link.js b/src/utils/Link.js @@ -0,0 +1,29 @@ +/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */ + +import invariant from 'react/lib/invariant'; +import AppActions from '../actions/AppActions'; + +function handleClick(event) { + + // If not left mouse click + if (event.button !== 0) { + return; + } + + // If modified event + if (event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) { + return; + } + + var el = event.target; + + invariant(el && el.nodeName === 'A', 'The target element must be a link.'); + + // Rebuild path + var path = el.pathname + el.search + (el.hash || ''); + + event.preventDefault(); + AppActions.navigateTo(path); +} + +export default { handleClick };