Skip to content

Commit 968354b

Browse files
committed
Refactor userSelect and add test.
1 parent c1c936c commit 968354b

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

lib/draggable.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,18 @@ function snapToGrid(grid, pendingX, pendingY) {
135135
var userSelectStyle = ';user-select: none;-webkit-user-select:none;-moz-user-select:none;' +
136136
'-o-user-select:none;-ms-user-select:none;';
137137

138+
function addUserSelectStyles(draggable) {
139+
if (!draggable.props.enableUserSelectHack) return;
140+
var style = document.body.getAttribute('style') || '';
141+
document.body.setAttribute('style', style + userSelectStyle);
142+
}
143+
144+
function removeUserSelectStyles(draggable) {
145+
if (!draggable.props.enableUserSelectHack) return;
146+
var style = document.body.getAttribute('style') || '';
147+
document.body.setAttribute('style', style.replace(userSelectStyle, ''));
148+
}
149+
138150
function createCSSTransform(style) {
139151
if (!style.x && !style.y) return {};
140152
// Replace unitless items with px
@@ -333,6 +345,7 @@ module.exports = React.createClass({
333345
// Remove any leftover event handlers
334346
removeEvent(window, dragEventFor['move'], this.handleDrag);
335347
removeEvent(window, dragEventFor['end'], this.handleDragEnd);
348+
removeUserSelectStyles(this);
336349
},
337350

338351
getDefaultProps: function () {
@@ -382,10 +395,7 @@ module.exports = React.createClass({
382395

383396
// Add a style to the body to disable user-select. This prevents text from
384397
// being selected all over the page.
385-
if (this.props.enableUserSelectHack) {
386-
var style = document.body.getAttribute('style') || '';
387-
document.body.setAttribute('style', style + userSelectStyle);
388-
}
398+
addUserSelectStyles(this);
389399

390400
var dragPoint = getControlPosition(e);
391401

@@ -412,11 +422,7 @@ module.exports = React.createClass({
412422
return;
413423
}
414424

415-
// Remove user-select styles.
416-
if (this.props.enableUserSelectHack) {
417-
var style = document.body.getAttribute('style') || '';
418-
document.body.setAttribute('style', style.replace(userSelectStyle, ''));
419-
}
425+
removeUserSelectStyles(this);
420426

421427
// Turn off dragging
422428
this.setState({

specs/draggable.spec.js

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ var React = require('react');
33
var TestUtils = require('react/lib/ReactTestUtils');
44
var Draggable = require('../index');
55

6-
/*global describe,it,expect */
6+
/*global describe,it,expect,afterEach */
77
describe('react-draggable', function () {
8+
var drag;
9+
afterEach(function() {
10+
if (drag && drag.getDOMNode) drag.componentWillUnmount();
11+
});
12+
813
describe('props', function () {
914
it('should have default properties', function () {
10-
var drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
15+
drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
1116

1217
expect(drag.props.axis).toEqual('both');
1318
expect(drag.props.handle).toEqual(null);
@@ -19,23 +24,21 @@ describe('react-draggable', function () {
1924
});
2025

2126
it('should pass style and className properly from child', function () {
22-
var el = <Draggable><div className="foo" style={{color: 'black'}}/></Draggable>;
27+
drag = <Draggable><div className="foo" style={{color: 'black'}}/></Draggable>;
2328
var renderer = TestUtils.createRenderer();
24-
renderer.render(el);
29+
renderer.render(drag);
2530
var output = renderer.getRenderOutput();
2631

2732
expect(output.props.className).toEqual('foo react-draggable');
2833
expect(output.props.style.color).toEqual('black');
29-
// This should get added
30-
expect(output.props.style.userSelect).toEqual('none');
3134
});
3235

3336
it('should honor props', function () {
3437
function handleStart() {}
3538
function handleDrag() {}
3639
function handleStop() {}
3740

38-
var drag = TestUtils.renderIntoDocument(
41+
drag = TestUtils.renderIntoDocument(
3942
<Draggable
4043
axis="y"
4144
handle=".handle"
@@ -64,7 +67,7 @@ describe('react-draggable', function () {
6467

6568
it('should call onStart when dragging begins', function () {
6669
var called = false;
67-
var drag = TestUtils.renderIntoDocument(
70+
drag = TestUtils.renderIntoDocument(
6871
<Draggable onStart={function () { called = true; }}>
6972
<div/>
7073
</Draggable>
@@ -76,7 +79,7 @@ describe('react-draggable', function () {
7679

7780
it('should call onStop when dragging ends', function () {
7881
var called = false;
79-
var drag = TestUtils.renderIntoDocument(
82+
drag = TestUtils.renderIntoDocument(
8083
<Draggable onStop={function () { called = true; }}>
8184
<div/>
8285
</Draggable>
@@ -88,7 +91,7 @@ describe('react-draggable', function () {
8891
});
8992

9093
it('should render with translate()', function () {
91-
var drag = TestUtils.renderIntoDocument(
94+
drag = TestUtils.renderIntoDocument(
9295
<Draggable>
9396
<div />
9497
</Draggable>
@@ -105,18 +108,37 @@ describe('react-draggable', function () {
105108
var style = node.getAttribute('style');
106109
expect(style.indexOf('transform: translate(100px, 100px);')).not.toEqual(-1);
107110
});
111+
112+
it('should add and remove user-select styles', function () {
113+
var userSelectStyle = ';user-select: none;-webkit-user-select:none;-moz-user-select:none;' +
114+
'-o-user-select:none;-ms-user-select:none;';
115+
116+
drag = TestUtils.renderIntoDocument(
117+
<Draggable>
118+
<div />
119+
</Draggable>
120+
);
121+
122+
var node = drag.getDOMNode();
123+
124+
expect(document.body.getAttribute('style')).toEqual('');
125+
TestUtils.Simulate.mouseDown(node, {clientX: 0, clientY: 0});
126+
expect(document.body.getAttribute('style')).toEqual(userSelectStyle);
127+
TestUtils.Simulate.mouseUp(node);
128+
expect(document.body.getAttribute('style')).toEqual('');
129+
});
108130
});
109131

110132
describe('interaction', function () {
111133
it('should initialize dragging onmousedown', function () {
112-
var drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
134+
drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
113135

114136
TestUtils.Simulate.mouseDown(drag.getDOMNode());
115137
expect(drag.state.dragging).toEqual(true);
116138
});
117139

118140
it('should only initialize dragging onmousedown of handle', function () {
119-
var drag = TestUtils.renderIntoDocument(
141+
drag = TestUtils.renderIntoDocument(
120142
<Draggable handle=".handle">
121143
<div>
122144
<div className="handle">Handle</div>
@@ -133,7 +155,7 @@ describe('react-draggable', function () {
133155
});
134156

135157
it('should not initialize dragging onmousedown of cancel', function () {
136-
var drag = TestUtils.renderIntoDocument(
158+
drag = TestUtils.renderIntoDocument(
137159
<Draggable cancel=".cancel">
138160
<div>
139161
<div className="cancel">Cancel</div>
@@ -150,7 +172,7 @@ describe('react-draggable', function () {
150172
});
151173

152174
it('should discontinue dragging onmouseup', function () {
153-
var drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
175+
drag = TestUtils.renderIntoDocument(<Draggable><div/></Draggable>);
154176

155177
TestUtils.Simulate.mouseDown(drag.getDOMNode());
156178
expect(drag.state.dragging).toEqual(true);
@@ -162,7 +184,7 @@ describe('react-draggable', function () {
162184

163185
describe('validation', function () {
164186
it('should result with invariant when there isn\'t any children', function () {
165-
var drag = (<Draggable/>);
187+
drag = (<Draggable/>);
166188

167189
var error = false;
168190
try {
@@ -175,7 +197,7 @@ describe('react-draggable', function () {
175197
});
176198

177199
it('should result with invariant if there\'s more than a single child', function () {
178-
var drag = (<Draggable><div/><div/></Draggable>);
200+
drag = (<Draggable><div/><div/></Draggable>);
179201

180202
var error = false;
181203
try {

0 commit comments

Comments
 (0)