Skip to content

Commit

Permalink
more tests, moved class manipulation to own module
Browse files Browse the repository at this point in the history
  • Loading branch information
bevacqua committed Jul 27, 2015
1 parent 82e1b4e commit 9e0d17b
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 29 deletions.
4 changes: 4 additions & 0 deletions changelog.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2.1.1 Classy Drake

- Fixed a bug where adding and removing classes might've caused issues on elements that had foreign CSS classes

# 2.1.0 Over and Out

- Added `over` event that fires whenever an element is dragged over a container _(or whenever a drag event starts)_
Expand Down
33 changes: 33 additions & 0 deletions classes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

var cache = {};
var start = '(?:^|\\s)';
var end = '(?:\\s|$)';

function lookupClass (className) {
var cached = cache[className];
if (cached) {
cached.lastIndex = 0;
} else {
cache[className] = cached = new RegExp(start + className + end, 'g');
}
return cached;
}

function addClass (el, className) {
var current = el.className;
if (!current.length) {
el.className = className;
} else if (!lookupClass(className).test(current)) {
el.className += ' ' + className;
}
}

function rmClass (el, className) {
el.className = el.className.replace(lookupClass(className), ' ').trim();
}

module.exports = {
add: addClass,
rm: rmClass
};
32 changes: 9 additions & 23 deletions dragula.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var emitter = require('contra/emitter');
var crossvent = require('crossvent');
var classes = require('./classes');

function dragula (initialContainers, options) {
var len = arguments.length;
Expand Down Expand Up @@ -107,7 +108,7 @@ function dragula (initialContainers, options) {
}

function renderMirrorAndDrag () {
addClass(_copy || _item, 'gu-transit');
classes.add(_copy || _item, 'gu-transit');
renderMirrorImage();
drag();
}
Expand Down Expand Up @@ -240,7 +241,7 @@ function dragula (initialContainers, options) {
var item = _copy || _item;
removeMirrorImage();
if (item) {
rmClass(item, 'gu-transit');
classes.rm(item, 'gu-transit');
}
if (_renderTimer) {
clearTimeout(_renderTimer);
Expand Down Expand Up @@ -346,17 +347,17 @@ function dragula (initialContainers, options) {
_mirror = _item.cloneNode(true);
_mirror.style.width = getRectWidth(rect) + 'px';
_mirror.style.height = getRectHeight(rect) + 'px';
rmClass(_mirror, 'gu-transit');
addClass(_mirror, ' gu-mirror');
classes.rm(_mirror, 'gu-transit');
classes.add(_mirror, ' gu-mirror');
body.appendChild(_mirror);
touchy(documentElement, 'add', 'mousemove', drag);
addClass(body, 'gu-unselectable');
classes.add(body, 'gu-unselectable');
drake.emit('cloned', _mirror, _item);
}

function removeMirrorImage () {
if (_mirror) {
rmClass(body, 'gu-unselectable');
classes.rm(body, 'gu-unselectable');
touchy(documentElement, 'remove', 'mousemove', drag);
_mirror.parentElement.removeChild(_mirror);
_mirror = null;
Expand Down Expand Up @@ -458,13 +459,8 @@ function getElementBehindPoint (point, x, y) {
return el;
}

function never () {
return false;
}

function always () {
return true;
}
function never () { return false; }
function always () { return true; }

function nextEl (el) {
return el.nextElementSibling || manually();
Expand All @@ -477,16 +473,6 @@ function nextEl (el) {
}
}

function addClass (el, className) {
if (el.className.indexOf(' ' + className) === -1) {
el.className += ' ' + className;
}
}

function rmClass (el, className) {
el.className = el.className.replace(new RegExp(' ' + className, 'g'), '');
}

function getEventHost (e) {
// on touchend event, we have to use `e.changedTouches`
// see http://stackoverflow.com/questions/7192563/touchend-event-properties
Expand Down
8 changes: 4 additions & 4 deletions example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ dragula([$('left1'), $('right1')]);
dragula([$('left2'), $('right2')], { copy: true });
dragula([$('left3'), $('right3')])
.on('drag', function (el) {
el.className = el.className.replace(' ex-moved', '');
el.className = el.className.replace('ex-moved', '');
}).on('drop', function (el) {
el.className += ' ex-moved';
}).on('over', function (el, container) {console.log('in',arguments);
}).on('over', function (el, container) {
container.className += ' ex-over';
}).on('out', function (el, container) {console.log('out',arguments);
container.className = container.className.replace(' ex-over', '');
}).on('out', function (el, container) {
container.className = container.className.replace('ex-over', '');
});
dragula([$('left4'), $('right4')], { revertOnSpill: true });
dragula([$('left5'), $('right5')], {
Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ <h3 class='tagline'>Drag and drop so simple it hurts</h3>
<code>
dragula([document.getElementById(left), document.getElementById(right)])
.on('drag', function (el) {
el.className = el.className.replace(' ex-moved', '');
el.className = el.className.replace('ex-moved', '');
}).on('drop', function (el) {
el.className += ' ex-moved';
}).on('over', function (el, container) {
container.className += ' ex-over';
}).on('out', function (el, container) {
container.className = container.className.replace(' ex-over', '');
container.className = container.className.replace('ex-over', '');
});
</code>
</pre>
Expand Down
65 changes: 65 additions & 0 deletions test/classes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict';

var test = require('tape');
var classes = require('../classes');

test('classes exports the expected api', function (t) {
t.equal(typeof classes.add, 'function', 'classes.add is a method');
t.equal(typeof classes.rm, 'function', 'classes.rm is a method');
t.end();
});

test('classes can add a class', function (t) {
var el = document.createElement('div');
classes.add(el, 'gu-foo');
t.equal(el.className, 'gu-foo', 'setting a class works');
t.end();
});

test('classes can add a class to an element that already has classes', function (t) {
var el = document.createElement('div');
el.className = 'bar';
classes.add(el, 'gu-foo');
t.equal(el.className, 'bar gu-foo', 'appending a class works');
t.end();
});

test('classes.add is a no-op if class already is in element', function (t) {
var el = document.createElement('div');
el.className = 'gu-foo';
classes.add(el, 'gu-foo');
t.equal(el.className, 'gu-foo', 'no-op as expected');
t.end();
});

test('classes can remove a class', function (t) {
var el = document.createElement('div');
el.className = 'gu-foo';
classes.rm(el, 'gu-foo');
t.equal(el.className, '', 'removing a class works');
t.end();
});

test('classes can remove a class from a list on the right', function (t) {
var el = document.createElement('div');
el.className = 'bar gu-foo';
classes.rm(el, 'gu-foo');
t.equal(el.className, 'bar', 'removing a class from the list works to the right');
t.end();
});

test('classes can remove a class from a list on the left', function (t) {
var el = document.createElement('div');
el.className = 'gu-foo bar';
classes.rm(el, 'gu-foo');
t.equal(el.className, 'bar', 'removing a class from the list works to the left');
t.end();
});

test('classes can remove a class from a list on the middle', function (t) {
var el = document.createElement('div');
el.className = 'foo gu-foo bar';
classes.rm(el, 'gu-foo');
t.equal(el.className, 'foo bar', 'removing a class from the list works to the middle');
t.end();
});
26 changes: 26 additions & 0 deletions test/defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

var test = require('tape');
var dragula = require('..');

test('drake has sensible default options', function (t) {
var options = {};
var drake = dragula(options);
t.equal(typeof options.moves, 'function', 'options.moves defaults to a method');
t.equal(typeof options.accepts, 'function', 'options.accepts defaults to a method');
t.equal(typeof options.invalid, 'function', 'options.invalid defaults to a method');
t.equal(typeof options.isContainer, 'function', 'options.isContainer defaults to a method');
t.equal(options.copy, false, 'options.copy defaults to false');
t.equal(options.revertOnSpill, false, 'options.revertOnSpill defaults to false');
t.equal(options.removeOnSpill, false, 'options.removeOnSpill defaults to false');
t.equal(options.delay, false, 'options.delay defaults to false');
t.equal(options.direction, 'vertical', 'options.direction defaults to \'vertical\'');
t.end();
});

test('delay: true means 300ms', function (t) {
var options = { delay: true };
var drake = dragula(options);
t.equal(options.delay, 300, 'options.delay=true gets casted to 300');
t.end();
});

0 comments on commit 9e0d17b

Please sign in to comment.