all files / modules/ Link.js

96.52% Statements 111/115
90.14% Branches 64/71
100% Functions 16/16
92.11% Lines 35/38
10 statements, 1 function, 14 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126                                                                                                                                                      50×       50× 50×   50×   50× 44× 14× 13×   14×         50×              
import React, { Component } from 'react'
 
const { bool, object, string, func } = React.PropTypes
 
function isLeftClickEvent(event) {
  return event.button === 0
}
 
function isModifiedEvent(event) {
  return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey)
}
 
function isEmptyObject(object) {
  for (let p in object)
    Eif (object.hasOwnProperty(p))
      return false
 
  return true
}
 
/**
 * A <Link> is used to create an <a> element that links to a route.
 * When that route is active, the link gets the value of its
 * `activeClassName` prop
 *
 * For example, assuming you have the following route:
 *
 *   <Route path="/posts/:postID" component={Post} />
 *
 * You could use the following component to link to that route:
 *
 *   <Link to={`/posts/${post.id}`} />
 *
 * Links may pass along location state and/or query string parameters
 * in the state/query props, respectively.
 *
 *   <Link ... query={{ show: true }} state={{ the: 'state' }} />
 */
class Link extends Component {
 
  static contextTypes = {
    history: object
  }
 
  static propTypes = {
    to: string.isRequired,
    query: object,
    hash: string,
    state: object,
    activeStyle: object,
    activeClassName: string,
    onlyActiveOnIndex: bool.isRequired,
    onClick: func
  }
 
  static defaultProps = {
    onlyActiveOnIndex: false,
    className: '',
    style: {}
  }
 
  handleClick(event) {
    let allowTransition = true
 
    Eif (this.props.onClick)
      this.props.onClick(event)
 
    if (isModifiedEvent(event) || !isLeftClickEvent(event))
      return
 
    if (event.defaultPrevented === true)
      allowTransition = false
 
    // If target prop is set (e.g. to "_blank") let browser handle link.
    Iif (this.props.target) {
      if (!allowTransition)
        event.preventDefault()
 
      return
    }
 
    event.preventDefault()
 
    if (allowTransition) {
      let { state, to, query, hash } = this.props
 
      Eif (hash)
        to += hash
 
      this.context.history.pushState(state, to, query)
    }
  }
 
  render() {
    const { to, query, hash, state, activeClassName, activeStyle, onlyActiveOnIndex, ...props } = this.props
 
    // Manually override onClick.
    props.onClick = (e) => this.handleClick(e)
 
    // Ignore if rendered outside the context of history, simplifies unit testing.
    const { history } = this.context
    Eif (history) {
      props.href = history.createHref(to, query)
 
      if (hash)
        props.href += hash
 
      if (activeClassName || (activeStyle != null && !isEmptyObject(activeStyle))) {
        if (history.isActive(to, query, onlyActiveOnIndex)) {
          if (activeClassName)
            props.className += props.className === '' ? activeClassName : ` ${activeClassName}`
 
          if (activeStyle)
            props.style = { ...props.style, ...activeStyle }
        }
      }
    }
 
    return <a {...props} />
  }
 
}
 
export default Link