diff --git a/src/sentry/static/sentry/app/components/events/interfaces/frame.jsx b/src/sentry/static/sentry/app/components/events/interfaces/frame.jsx index 292e9ddb92a7ca..b2b9dbc051ecdf 100644 --- a/src/sentry/static/sentry/app/components/events/interfaces/frame.jsx +++ b/src/sentry/static/sentry/app/components/events/interfaces/frame.jsx @@ -6,6 +6,7 @@ import {defined, objectIsEmpty, isUrl} from '../../../utils'; import TooltipMixin from '../../../mixins/tooltip'; import FrameVariables from './frameVariables'; import ContextLine from './contextLine'; +import StrictClick from '../../strictClick'; import {t} from '../../../locale'; function trimPackage(pkg) { @@ -183,21 +184,22 @@ const Frame = React.createClass({ if (hasContextSource || hasContextVars) { let startLineNo = hasContextSource ? data.context[0][0] : ''; context = ( -
    - {defined(data.errors) && -
  1. {data.errors.join(', ')}
  2. - } - - {data.context && contextLines.map((line, index) => { - return ; - })} - - {hasContextVars && - - } -
+ +
    + {defined(data.errors) && +
  1. {data.errors.join(', ')}
  2. + } + + {data.context && contextLines.map((line, index) => { + return ; + })} + + {hasContextVars && + + } +
+
); } return context; diff --git a/src/sentry/static/sentry/app/components/strictClick.jsx b/src/sentry/static/sentry/app/components/strictClick.jsx new file mode 100644 index 00000000000000..49560defe415d4 --- /dev/null +++ b/src/sentry/static/sentry/app/components/strictClick.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; + +/** + * Usage: + * + * + * + */ +const StrictClick = React.createClass({ + propTypes: { + onClick: React.PropTypes.func.isRequired + }, + + mixins: [ + PureRenderMixin + ], + + statics: { + MAX_DELTA_X: 10, + MAX_DELTA_Y: 10 + }, + + getInitialState() { + return { + startCoords: null + }; + }, + + handleMouseDown: function(evt) { + this.setState({ + startCoords: { + x: evt.screenX, + y: evt.screenY + } + }); + }, + + handleMouseClick: function(evt) { + // Click happens if mouse down/up in same element - click will + // not fire if either initial mouse down OR final ouse up occurs in + // different element + let {startCoords} = this.state; + let deltaX = evt.screenX - startCoords.x; + let deltaY = evt.screenY - startCoords.y; + + // If mouse hasn't moved more than 10 pixels in either Y + // or X direction, fire onClick + if (deltaX < StrictClick.MAX_DELTA_X && deltaY < StrictClick.MAX_DELTA_Y) { + this.props.onClick(evt); + } + this.setState({ + startCoords: null + }); + }, + + render() { + return React.cloneElement(this.props.children, { + onMouseDown: this.handleMouseDown, + onClick: this.handleMouseClick + }); + } +}); + +export default StrictClick; +