Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions src/sentry/static/sentry/app/components/events/interfaces/frame.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -183,21 +184,22 @@ const Frame = React.createClass({
if (hasContextSource || hasContextVars) {
let startLineNo = hasContextSource ? data.context[0][0] : '';
context = (
<ol start={startLineNo} className={outerClassName}
onClick={expandable ? this.toggleContext : null}>
{defined(data.errors) &&
<li className={expandable ? 'expandable error' : 'error'}
key="errors">{data.errors.join(', ')}</li>
}

{data.context && contextLines.map((line, index) => {
return <ContextLine key={index} line={line} isActive={data.lineNo === line[0]}/>;
})}

{hasContextVars &&
<FrameVariables data={data.vars} key="vars" />
}
</ol>
<StrictClick onClick={expandable ? this.toggleContext : null}>
<ol start={startLineNo} className={outerClassName}>
{defined(data.errors) &&
<li className={expandable ? 'expandable error' : 'error'}
key="errors">{data.errors.join(', ')}</li>
}

{data.context && contextLines.map((line, index) => {
return <ContextLine key={index} line={line} isActive={data.lineNo === line[0]}/>;
})}

{hasContextVars &&
<FrameVariables data={data.vars} key="vars" />
}
</ol>
</StrictClick>
);
}
return context;
Expand Down
66 changes: 66 additions & 0 deletions src/sentry/static/sentry/app/components/strictClick.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';

/**
* Usage:
* <StrictClick onClick={this.onClickHandler}>
* <button>Some button</button>
* </StrictClick>
*/
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, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is cloning the children, does this end up with two layers in DOM? An <ol> inside an <ol>? Or am I just misunderstanding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot replace props on an existing object. So this creates a clone (with new onClick and onMouseMove props) and renders that clone instead. It doesn't render two <ol> elements.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, clever.

onMouseDown: this.handleMouseDown,
onClick: this.handleMouseClick
});
}
});

export default StrictClick;