Add test for using function to select element

Move dockblock

Fix import path for closest

Resolving merge conflict error

Fix linting errors
This commit is contained in:
Tim Rourke 2017-11-03 10:13:32 -05:00
parent aaa5c2b597
commit d91e2afef8
3 changed files with 23 additions and 63 deletions

View File

@ -3,6 +3,15 @@ const matchFunction = Element.prototype.matches ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector;
/**
* Get the closest parent element of a given element that matches the given
* selector string or matching function
*
* @param {Element} element The child element to find a parent of
* @param {String|Function} selector The string or function to use to match
* the parent element
* @return {Element|null}
*/
export default function closest(element, value) {
if (!element) {
return null;

View File

@ -1,9 +1,9 @@
import {closest} from 'utils';
import {
createSandbox,
} from 'helper';
import closest from './../closest';
const sampleMarkup = `
<div class="tree">
<section class="branch">
@ -48,6 +48,18 @@ describe('utils', () => {
expect(closest(element, '.leaf')).toBe(null);
});
test('should match element via callback', () => {
const element = sandbox.querySelector('.leaf');
function callback(currentElement) {
return currentElement
.classList
.contains('leaf');
}
expect(closest(element, callback)).toBe(element);
});
[
'.twig',
'ul',

View File

@ -1,61 +0,0 @@
/** @module utils */
/**
* Get the closest parent element of a given element that matches the given
* selector string or matching function
*
* @param {Element} element The child element to find a parent of
* @param {String|Function} selector The string or function to use to match
* the parent element
* @return {Element|null}
*/
export function closest(element, selector) {
if (!element) {
return null;
}
function conditionFn(currentElement) {
if (!currentElement) {
return currentElement;
} else if (typeof selector === 'string') {
const matchFunction = Element.prototype.matches ||
Element.prototype.webkitMatchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector;
return matchFunction.call(currentElement, selector);
} else {
return selector(currentElement);
}
}
let current = element;
do {
current = current.correspondingUseElement || current.correspondingElement || current;
if (conditionFn(current)) {
return current;
}
current = current.parentNode;
} while (current !== document.body && current !== document);
return null;
}
let scrollAnimationFrame;
export function scroll(element, {clientX, clientY, speed, sensitivity}) {
if (scrollAnimationFrame) {
cancelAnimationFrame(scrollAnimationFrame);
}
function scrollFn() {
const rect = element.getBoundingClientRect();
const offsetY = (Math.abs(rect.bottom - clientY) <= sensitivity) - (Math.abs(rect.top - clientY) <= sensitivity);
const offsetX = (Math.abs(rect.right - clientX) <= sensitivity) - (Math.abs(rect.left - clientX) <= sensitivity);
element.scrollTop += offsetY * speed;
element.scrollLeft += offsetX * speed;
scrollAnimationFrame = requestAnimationFrame(scrollFn);
}
scrollAnimationFrame = requestAnimationFrame(scrollFn);
}