mirror of
https://github.com/tenrok/OverlayScrollbars.git
synced 2026-05-17 03:59:39 +03:00
355 lines
11 KiB
TypeScript
355 lines
11 KiB
TypeScript
import { createDiv, contents, appendChildren, prependChildren, insertBefore, insertAfter, removeElements } from 'support/dom';
|
|
import { each, isArray, isHTMLElement } from 'support/utils';
|
|
|
|
const slotElm = document.body;
|
|
const fillSlotElm = () => {
|
|
const content = [createDiv(), createDiv(), createDiv(), createDiv(), createDiv()];
|
|
content.forEach((elm, i) => {
|
|
elm.setAttribute('id', i.toString());
|
|
slotElm.append(elm);
|
|
});
|
|
};
|
|
const clearSlotElm = () => {
|
|
contents(slotElm).forEach((elm) => {
|
|
elm.remove();
|
|
});
|
|
};
|
|
const compareToNative = (
|
|
target: Node,
|
|
method: string,
|
|
snapshot: Array<Node>,
|
|
elms: Element | Node | Array<Element> | Array<Node>,
|
|
compareIds = false,
|
|
) => {
|
|
if (!compareIds) {
|
|
if (!isArray(elms)) {
|
|
elms = [elms];
|
|
}
|
|
elms.forEach((e) => {
|
|
if (isHTMLElement(e)) {
|
|
e.remove();
|
|
}
|
|
});
|
|
target[method](...elms);
|
|
expect(Array.from(slotElm.childNodes)).toEqual(snapshot);
|
|
} else {
|
|
clearSlotElm();
|
|
fillSlotElm();
|
|
|
|
if (!isArray(elms)) {
|
|
elms = [elms];
|
|
}
|
|
|
|
const realElms: Array<Element> = [];
|
|
elms.forEach((elm) => {
|
|
slotElm.childNodes.forEach((child) => {
|
|
if (isHTMLElement(child)) {
|
|
if (isHTMLElement(elm) && child.getAttribute('id') === elm.getAttribute('id')) {
|
|
realElms.push(child);
|
|
}
|
|
if (compareIds && target !== slotElm && isHTMLElement(target) && child.getAttribute('id') === target.getAttribute('id')) {
|
|
target = child;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
target[method](...realElms);
|
|
|
|
const mapIds = (elm: Node) => (isHTMLElement(elm) ? elm.getAttribute('id') || '' : '');
|
|
const snapshotIdArr: Array<string> = snapshot.map(mapIds);
|
|
const elmsIdArr: Array<string> = Array.from(slotElm.childNodes).map(mapIds);
|
|
|
|
expect(JSON.stringify(elmsIdArr)).toEqual(JSON.stringify(snapshotIdArr));
|
|
}
|
|
};
|
|
|
|
describe('dom manipulation', () => {
|
|
beforeEach(() => fillSlotElm());
|
|
afterEach(() => clearSlotElm());
|
|
|
|
describe('appendChildren', () => {
|
|
test('single created', () => {
|
|
const createdDiv = createDiv();
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
appendChildren(slotElm, createdDiv);
|
|
expect(createdDiv).toBe(childNodes[childNodes.length - 1]);
|
|
expect(childNodes.length).toBe(length + 1);
|
|
|
|
compareToNative(slotElm, 'append', Array.from(childNodes), createdDiv);
|
|
});
|
|
|
|
test('multiple created', () => {
|
|
const createdDivs = [createDiv(), createDiv(), createDiv()];
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
appendChildren(slotElm, createdDivs);
|
|
expect(createdDivs[0]).toBe(childNodes[childNodes.length - 3]);
|
|
expect(createdDivs[1]).toBe(childNodes[childNodes.length - 2]);
|
|
expect(createdDivs[2]).toBe(childNodes[childNodes.length - 1]);
|
|
expect(childNodes.length).toBe(length + createdDivs.length);
|
|
|
|
compareToNative(slotElm, 'append', Array.from(childNodes), createdDivs);
|
|
});
|
|
|
|
test('single existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const elm = childNodes[1];
|
|
|
|
appendChildren(slotElm, elm);
|
|
expect(elm).toBe(childNodes[childNodes.length - 1]);
|
|
|
|
compareToNative(slotElm, 'append', Array.from(childNodes), elm, true);
|
|
});
|
|
|
|
test('multiple existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const elms = [childNodes[1], childNodes[0], childNodes[2]];
|
|
|
|
appendChildren(slotElm, elms);
|
|
expect(elms[0]).toBe(childNodes[childNodes.length - 3]);
|
|
expect(elms[1]).toBe(childNodes[childNodes.length - 2]);
|
|
expect(elms[2]).toBe(childNodes[childNodes.length - 1]);
|
|
|
|
compareToNative(slotElm, 'append', Array.from(childNodes), elms, true);
|
|
});
|
|
|
|
test('none', () => {
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
appendChildren(slotElm, null);
|
|
appendChildren(null, childNodes);
|
|
|
|
expect(childNodes.length).toBe(length);
|
|
});
|
|
});
|
|
|
|
describe('prependChildren', () => {
|
|
test('single created', () => {
|
|
const createdDiv = createDiv();
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
prependChildren(slotElm, createdDiv);
|
|
expect(createdDiv).toBe(childNodes[0]);
|
|
expect(childNodes.length).toBe(length + 1);
|
|
|
|
compareToNative(slotElm, 'prepend', Array.from(childNodes), createdDiv);
|
|
});
|
|
|
|
test('multiple created', () => {
|
|
const createdDivs = [createDiv(), createDiv(), createDiv()];
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
prependChildren(slotElm, createdDivs);
|
|
expect(createdDivs[0]).toBe(childNodes[0]);
|
|
expect(createdDivs[1]).toBe(childNodes[1]);
|
|
expect(createdDivs[2]).toBe(childNodes[2]);
|
|
expect(childNodes.length).toBe(length + createdDivs.length);
|
|
|
|
compareToNative(slotElm, 'prepend', Array.from(childNodes), createdDivs);
|
|
});
|
|
|
|
test('single existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const elm = childNodes[1];
|
|
|
|
prependChildren(slotElm, elm);
|
|
expect(elm).toBe(childNodes[0]);
|
|
|
|
compareToNative(slotElm, 'prepend', Array.from(childNodes), elm, true);
|
|
});
|
|
|
|
test('multiple existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const elms = [childNodes[1], childNodes[0], childNodes[2]];
|
|
|
|
prependChildren(slotElm, elms);
|
|
expect(elms[0]).toBe(childNodes[0]);
|
|
expect(elms[1]).toBe(childNodes[1]);
|
|
expect(elms[2]).toBe(childNodes[2]);
|
|
|
|
compareToNative(slotElm, 'prepend', Array.from(childNodes), elms, true);
|
|
});
|
|
|
|
test('none', () => {
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
prependChildren(slotElm, null);
|
|
prependChildren(null, childNodes);
|
|
|
|
expect(childNodes.length).toBe(length);
|
|
});
|
|
});
|
|
|
|
describe('insertBefore', () => {
|
|
test('single created', () => {
|
|
const createdDiv = createDiv();
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
const target = childNodes[1];
|
|
|
|
insertBefore(target, createdDiv);
|
|
expect(createdDiv).toBe(childNodes[1]);
|
|
expect(childNodes.length).toBe(length + 1);
|
|
|
|
compareToNative(target, 'before', Array.from(childNodes), createdDiv);
|
|
});
|
|
|
|
test('multiple created', () => {
|
|
const createdDivs = [createDiv(), createDiv(), createDiv()];
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
const target = childNodes[1];
|
|
|
|
insertBefore(target, createdDivs);
|
|
expect(createdDivs[0]).toBe(childNodes[1]);
|
|
expect(createdDivs[1]).toBe(childNodes[2]);
|
|
expect(createdDivs[2]).toBe(childNodes[3]);
|
|
expect(childNodes.length).toBe(length + createdDivs.length);
|
|
|
|
compareToNative(target, 'before', Array.from(childNodes), createdDivs);
|
|
});
|
|
|
|
test('single existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const target = childNodes[1];
|
|
const elm = childNodes[2];
|
|
|
|
insertBefore(target, elm);
|
|
expect(elm).toBe(childNodes[1]);
|
|
|
|
compareToNative(target, 'before', Array.from(childNodes), elm, true);
|
|
});
|
|
|
|
test('multiple existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const target = childNodes[1];
|
|
const elms = [childNodes[4], childNodes[1], childNodes[2]];
|
|
|
|
insertBefore(target, elms);
|
|
expect(elms[0]).toBe(childNodes[1]);
|
|
expect(elms[1]).toBe(childNodes[2]);
|
|
expect(elms[2]).toBe(childNodes[3]);
|
|
|
|
compareToNative(target, 'before', Array.from(childNodes), elms, true);
|
|
});
|
|
|
|
test('none', () => {
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
insertBefore(slotElm, null);
|
|
insertBefore(null, childNodes);
|
|
|
|
expect(childNodes.length).toBe(length);
|
|
});
|
|
});
|
|
|
|
describe('insertAfter', () => {
|
|
test('single created', () => {
|
|
const createdDiv = createDiv();
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
const target = childNodes[1];
|
|
|
|
insertAfter(target, createdDiv);
|
|
expect(createdDiv).toBe(childNodes[2]);
|
|
expect(childNodes.length).toBe(length + 1);
|
|
|
|
compareToNative(target, 'after', Array.from(childNodes), createdDiv);
|
|
});
|
|
|
|
test('multiple created', () => {
|
|
const createdDivs = [createDiv(), createDiv(), createDiv()];
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
const target = childNodes[1];
|
|
|
|
insertAfter(target, createdDivs);
|
|
expect(createdDivs[0]).toBe(childNodes[2]);
|
|
expect(createdDivs[1]).toBe(childNodes[3]);
|
|
expect(createdDivs[2]).toBe(childNodes[4]);
|
|
expect(childNodes.length).toBe(length + createdDivs.length);
|
|
|
|
compareToNative(target, 'after', Array.from(childNodes), createdDivs);
|
|
});
|
|
|
|
test('single existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const target = childNodes[1];
|
|
const elm = childNodes[0];
|
|
|
|
insertAfter(target, elm);
|
|
expect(elm).toBe(childNodes[1]);
|
|
|
|
compareToNative(target, 'after', Array.from(childNodes), elm, true);
|
|
});
|
|
|
|
test('multiple existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const target = childNodes[1];
|
|
const elms = [childNodes[4], childNodes[1], childNodes[2]];
|
|
|
|
insertAfter(target, elms);
|
|
expect(elms[0]).toBe(childNodes[1]);
|
|
expect(elms[1]).toBe(childNodes[2]);
|
|
expect(elms[2]).toBe(childNodes[3]);
|
|
|
|
compareToNative(target, 'after', Array.from(childNodes), elms, true);
|
|
});
|
|
|
|
test('none', () => {
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
|
|
insertAfter(slotElm, null);
|
|
insertAfter(null, childNodes);
|
|
|
|
expect(childNodes.length).toBe(length);
|
|
});
|
|
});
|
|
|
|
describe('removeElm', () => {
|
|
test('single created', () => {
|
|
const createdDiv = createDiv();
|
|
expect(createdDiv.parentElement).toBeNull();
|
|
removeElements(createdDiv);
|
|
});
|
|
|
|
test('multiple created', () => {
|
|
const createdDivs: Array<HTMLElement> = [createDiv(), createDiv(), createDiv(), createDiv()];
|
|
each(createdDivs, (createdDiv: HTMLElement) => {
|
|
expect(createdDiv.parentElement).toBeNull();
|
|
});
|
|
removeElements(createdDivs);
|
|
});
|
|
|
|
test('single existing', () => {
|
|
const { childNodes } = slotElm;
|
|
const { length } = childNodes;
|
|
expect(length).not.toBe(0);
|
|
removeElements(childNodes[0]);
|
|
expect(childNodes.length).toBe(length - 1);
|
|
});
|
|
|
|
test('multiple existing', () => {
|
|
const { childNodes } = slotElm;
|
|
expect(childNodes.length).not.toBe(0);
|
|
removeElements(childNodes);
|
|
expect(childNodes.length).toBe(0);
|
|
});
|
|
|
|
test('none', () => {
|
|
// @ts-ignore
|
|
removeElements(null);
|
|
});
|
|
});
|
|
});
|