Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ npm-debug.log
.idea
test/domassist.test.dist.js
dist
*js.map
61 changes: 61 additions & 0 deletions lib/idStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const storage = new Map();
Copy link
Member

Choose a reason for hiding this comment

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

what does this turn into after running through babel? A little worried that this bloats the code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing strange, Map is well supported.

Copy link
Member

Choose a reason for hiding this comment

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

if we have to support anything older than IE 11, this will error, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will yes, but that'd the least of our problems, lots of things are being used with no support below IE11. Attrobj being the first one which is deep into Domodule. Can use a regular object if you'd still like to strike for IE10 support but this is more performant for the use we are doing.


const idStorage = {
areSimilar(a, b) {
const everyKey = f => Object.keys(a).every(f);
const type = ({}).toString
.call(a)
.match(/\[object (\w+)\]/)[1];

switch (type) {
case 'Array':
return a.length === b.length &&
everyKey(k => idStorage.areSimilar(a.sort()[k], b.sort()[k]));
case 'Object':
return Object.keys(a).length === Object.keys(b).length &&
everyKey(k => idStorage.areSimilar(a[k], b[k]));
default:
return a === b;
}
},

add(data) {
const id = idStorage.generateID();
storage.set(id, data);

return id;
},

generateID() {
const h = n => (n | 0).toString(16);
const s = n => h((Math.random() * (1 << (n << 2))) ^ Date.now()).slice(-n);

return [
s(4) + s(4), s(4),
`4${s(3)}`,
h(8 | (Math.random() * 4)) + s(3),
Date.now().toString(16).slice(-10) + s(2)
].join('-');
},

removeFromID(id) {
const val = storage.get(id);
storage.delete(id);

return val;
},

removeFromValue(value) {
let found = null;

storage.forEach((val, key) => {
if (!found && idStorage.areSimilar(val, value)) {
found = key;
}
});

return idStorage.removeFromID(found);
}
};

export default idStorage;
9 changes: 4 additions & 5 deletions lib/modify.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import on from './on';
import styles from './styles';

function bindEvents(el, events) {
Object.keys(events).forEach((event) => {
on(el, event, events[event]);
});
return Object.keys(events).map(event => on(el, event, events[event]));
}

function modify(selector, params) {
Expand All @@ -25,11 +23,12 @@ function modify(selector, params) {
const els = find(selector);
if (els.length) {
els.forEach((el) => {
Object.keys(params).forEach((param, index) => {
Object.keys(params).forEach(param => {
if (param in modules) {
if (param === 'events') {
bindEvents(el, params[param]);
return bindEvents(el, params[param]);
}

modules[param](el, params[param]);
}
});
Expand Down
29 changes: 20 additions & 9 deletions lib/off.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import find from './find';
import idStorage from './idStorage';

function off(selector, event) {
function off(selector, event, handler, capture = false) {
if (Array.isArray(selector)) {
selector.forEach((item) => off(item, event));
}
if (!window._domassistevents) {
window._domassistevents = {};
selector.forEach((item) => off(item, event, handler, capture));
}

const data = window._domassistevents[`_${event}`];
// ID
if (typeof selector === 'string' && typeof event === 'undefined') {
const data = idStorage.removeFromID(selector);

if (!data) {
return;
}

if (!data) {
return;
return off(data.el, data.event, data.handler, data.capture);
}

const el = find(selector);

if (el.length) {
el.forEach((item) => {
item.removeEventListener(event, data.cb, data.capture);
item.removeEventListener(event, handler);
idStorage.removeFromValue({
el: item,
event,
handler,
capture
});
});
}
}
Expand Down
36 changes: 21 additions & 15 deletions lib/on.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
import find from './find';
import idStorage from './idStorage';

function on(selector, event, cb, capture = false) {
function on(selector, event, handler, capture = false) {
if (Array.isArray(selector)) {
selector.forEach((item) => on(item, event, cb, capture));
return;
return Array.prototype.concat.apply([],
selector.map(item => on(item, event, handler, capture)));
}

const data = {
cb,
capture
};

if (!window._domassistevents) {
window._domassistevents = {};
}

window._domassistevents[`_${event}`] = data;
const el = find(selector);
let ids = null;

if (el.length) {
el.forEach((item) => {
item.addEventListener(event, cb, capture);
ids = el.map(item => {
item.addEventListener(event, handler);

return idStorage.add({
el: item,
event,
handler,
capture
});
});

if (ids.length === 1) {
ids = ids[0];
}
}

return ids;
}

export default on;
22 changes: 18 additions & 4 deletions lib/once.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import on from './on';
import off from './off';
import find from './find';

function once(el, event, run, capture = false) {
on(el, event, e => {
off(el, event);
run(e);
function once(selector, event, handler, capture = false) {
if (Array.isArray(selector)) {
selector.forEach(item => once(item, event, handler, capture));
return;
}

const el = find(selector);

if (el.length > 1) {
// Need to get the event id for each element so once runs properly
once(el, event, handler, capture);
return;
}

const eventId = on(el, event, e => {
off(eventId);
handler(e);
}, capture);
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"devDependencies": {
"eslint-config-firstandthird": "3.2.0",
"eslint-plugin-import": "^2.1.0",
"map-polyfill": "0.0.1",
Copy link
Member

Choose a reason for hiding this comment

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

what is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So phantom is happy

"phantomjs-prebuilt": "^2.1.14",
"scriptkit": "0.2.0",
"static-server": "^2.0.3",
Expand Down
30 changes: 13 additions & 17 deletions test/domassist.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint no-console: 0 */

import '../node_modules/map-polyfill/dist/map.min';
import domassist from '../domassist';
import test from 'tape-rollup';
import { teardown } from './setup';
Expand All @@ -14,8 +15,7 @@ import './modify.test';
import './show-hide.test';
import './styles.test';
import './append.test';

const page = window.phantom.page;
import TestUtils from './test-utils';

test('ready', assert => {
// if you add more assertions update this number
Expand Down Expand Up @@ -117,9 +117,7 @@ test('Events - delegate', assert => {
`;

const button = domassist.findOne('button', el);
const pos = button.getBoundingClientRect();

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
button.click();
});

test('Events - once', assert => {
Expand All @@ -130,17 +128,15 @@ test('Events - once', assert => {
`;

const link = domassist.findOne('a', el);
const pos = link.getBoundingClientRect();

let clicks = 0;

domassist.once(link, 'click', e => {
clicks++;
});

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
link.click();
link.click();
link.click();

setTimeout(() => {
assert.equal(clicks, 1, 'Only fired once');
Expand All @@ -152,21 +148,21 @@ test('Events - hover', assert => {
const el = domassist.findOne('#domassist');

el.innerHTML = `
<div style="height: 100px; width: 100px;"></div>
<div></div>
`;

const box = domassist.findOne('div', el);
const pos = box.getBoundingClientRect();

domassist.hover(box, e => {
assert.ok(e instanceof MouseEvent, 'Enter fired');
assert.pass('Enter fired');
assert.equal(e.type, 'mouseenter', 'Correct event');
}, e => {
assert.ok(e instanceof MouseEvent, 'Leave fired');
assert.pass('Leave fired');
assert.equal(e.type, 'mouseleave', 'Correct event');
assert.end();
});

page.sendEvent('mousemove', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('mousemove', pos.left + pos.width + 100, pos.top + pos.height + 100);
TestUtils.fireEvent(box, 'mouseenter');
TestUtils.fireEvent(box, 'mouseleave');

assert.end();
});
13 changes: 13 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="domassist.test.dist.js"></script>
</body>
</html>
19 changes: 8 additions & 11 deletions test/modify.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import domassist from '../domassist';
import test from 'tape-rollup';
import TestUtils from './test-utils';

const setup = (total) => {
const frag = document.createDocumentFragment();
Expand All @@ -21,8 +22,6 @@ const teardown = (el) => {
}
};

const page = window.phantom.page;

test('modify - add class', assert => {
const el = domassist.findOne('#domassist');
domassist.modify(el, {
Expand Down Expand Up @@ -71,33 +70,31 @@ test('modify - html', assert => {
});
//
test('modify - events', assert => {
// assert.plan(5);
const el = domassist.findOne('#domassist');
el.innerHTML = `
<a style="display: block; height: 100px; width: 100px;" href="#">Click</a>
`;
const link = domassist.findOne('a');
const pos = link.getBoundingClientRect();
domassist.modify(link, {
events: {
click: (e) => {
assert.ok(e instanceof MouseEvent, 'Click event fired');
assert.pass('Click fired');
},
mouseenter: (e) => {
assert.ok(e instanceof MouseEvent, 'Enter fired');
assert.pass('Enter fired');
assert.equal(e.type, 'mouseenter', 'Correct event');
},
mouseleave: (e) => {
assert.ok(e instanceof MouseEvent, 'Leave fired');
assert.pass('Leave fired');
assert.equal(e.type, 'mouseleave', 'Correct event');
assert.end();
}
}
});

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('mousemove', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('mousemove', pos.left + pos.width + 100, pos.top + pos.height + 100);
link.click();
TestUtils.fireEvent(link, 'mouseenter');
TestUtils.fireEvent(link, 'mouseleave');
assert.end();
});
test('modify - styles', assert => {
const el = domassist.findOne('#domassist');
Expand Down
Loading