improve code and fix tests

This commit is contained in:
Rene Haas
2022-07-29 17:05:59 +02:00
parent 0fb35b5ae3
commit 2e587409a2
13 changed files with 374 additions and 268 deletions
@@ -1,4 +1,4 @@
import { assignDeep, each, isArray, keys } from 'support'; import { each, isArray, keys } from 'support';
import { OverlayScrollbars, OverlayScrollbarsStatic } from 'overlayscrollbars'; import { OverlayScrollbars, OverlayScrollbarsStatic } from 'overlayscrollbars';
export type PluginInstance = export type PluginInstance =
@@ -10,12 +10,11 @@ export type Plugin<T extends PluginInstance = PluginInstance> = {
const pluginRegistry: Record<string, PluginInstance> = {}; const pluginRegistry: Record<string, PluginInstance> = {};
export const getPlugins = () => assignDeep({}, pluginRegistry); export const getPlugins = () => pluginRegistry;
export const addPlugin = (addedPlugin: Plugin | Plugin[]) => { export const addPlugin = (addedPlugin: Plugin | Plugin[]) => {
each((isArray(addedPlugin) ? addedPlugin : [addedPlugin]) as Plugin[], (plugin) => { each((isArray(addedPlugin) ? addedPlugin : [addedPlugin]) as Plugin[], (plugin) => {
each(keys(plugin), (pluginName) => { const pluginName = keys(plugin)[0];
pluginRegistry[pluginName] = plugin[pluginName]; pluginRegistry[pluginName] = plugin[pluginName];
});
}); });
}; };
@@ -20,7 +20,7 @@ export type StructureDynamicInitializationElement = DynamicInitializationElement
* If element is provided, the provided element takes all its responsibilities. * If element is provided, the provided element takes all its responsibilities.
* DOM hierarchy isn't checked in this case, its assumed that hieararchy is correct in such a case. * DOM hierarchy isn't checked in this case, its assumed that hieararchy is correct in such a case.
* *
* Null or Undefined means that the environment initialization strategy is used. * undefined means that the default initialization strategy is used.
*/ */
export interface StructureInitialization { export interface StructureInitialization {
target: InitializationTargetElement; target: InitializationTargetElement;
@@ -1,7 +0,0 @@
export const mouseButton = (event: MouseEvent): number => {
const { button } = event;
if (!event.which && button !== undefined) {
return button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0; // eslint-disable-line no-bitwise
}
return event.which;
};
@@ -1,3 +1,2 @@
export * from 'support/compatibility/vendors'; export * from 'support/compatibility/vendors';
export * from 'support/compatibility/apis'; export * from 'support/compatibility/apis';
export * from 'support/compatibility/events';
@@ -105,11 +105,15 @@ const liesBetween = (
): boolean => { ): boolean => {
const closestHighBoundaryElm = elm && closest(elm, highBoundarySelector); const closestHighBoundaryElm = elm && closest(elm, highBoundarySelector);
const closestDeepBoundaryElm = elm && findFirst(deepBoundarySelector, closestHighBoundaryElm); const closestDeepBoundaryElm = elm && findFirst(deepBoundarySelector, closestHighBoundaryElm);
const deepBoundaryIsValid =
closest(closestDeepBoundaryElm, highBoundarySelector) === closestHighBoundaryElm;
return closestHighBoundaryElm && closestDeepBoundaryElm return closestHighBoundaryElm && closestDeepBoundaryElm
? closestHighBoundaryElm === elm || ? closestHighBoundaryElm === elm ||
closestDeepBoundaryElm === elm || closestDeepBoundaryElm === elm ||
closest(closest(elm, deepBoundarySelector), highBoundarySelector) !== closestHighBoundaryElm (deepBoundaryIsValid &&
closest(closest(elm, deepBoundarySelector), highBoundarySelector) !==
closestHighBoundaryElm)
: false; : false;
}; };
@@ -3,36 +3,26 @@ import { defaultOptions, getOptionsDiff } from 'options';
describe('options', () => { describe('options', () => {
test('defaultOptions', () => { test('defaultOptions', () => {
expect(defaultOptions).toEqual({ expect(defaultOptions).toEqual({
resize: 'none',
paddingAbsolute: false, paddingAbsolute: false,
showNativeOverlaidScrollbars: false,
updating: { updating: {
elementEvents: [['img', 'load']], elementEvents: [['img', 'load']],
attributes: null,
debounce: [0, 33], debounce: [0, 33],
attributes: null,
ignoreMutation: null,
}, },
overflow: { overflow: {
x: 'scroll', x: 'scroll',
y: 'scroll', y: 'scroll',
}, },
scrollbars: { scrollbars: {
theme: 'os-theme-dark',
visibility: 'auto', visibility: 'auto',
autoHide: 'never', autoHide: 'never',
autoHideDelay: 800, autoHideDelay: 1300,
dragScroll: true, dragScroll: true,
clickScroll: false, clickScroll: false,
touch: true, pointers: ['mouse', 'touch', 'pen'],
},
textarea: {
dynWidth: false,
dynHeight: false,
inheritedAttrs: ['style', 'class'],
},
nativeScrollbarsOverlaid: {
show: false,
initialize: false,
},
callbacks: {
onUpdated: null,
}, },
}); });
}); });
@@ -1,8 +1,12 @@
import { defaultOptions } from 'options'; import { defaultOptions } from 'options';
import { optionsValidationPlugin, optionsValidationPluginName } from 'plugins/optionsValidation'; import {
optionsValidationPlugin,
optionsValidationPluginName,
} from 'plugins/optionsValidationPlugin';
const getValidationFn = () => { const getValidationFn = () => {
const [name, instance] = optionsValidationPlugin; const name = Object.keys(optionsValidationPlugin)[0];
const instance = optionsValidationPlugin[name];
const validationFn = instance._; const validationFn = instance._;
expect(name).toBe(optionsValidationPluginName); expect(name).toBe(optionsValidationPluginName);
@@ -2,11 +2,11 @@ import { PlainObject } from 'typings';
import { import {
optionsTemplateTypes as oTypes, optionsTemplateTypes as oTypes,
OptionsTemplate, OptionsTemplate,
} from 'plugins/optionsValidation/validation'; } from 'plugins/optionsValidationPlugin/validation';
import { import {
transformOptions, transformOptions,
OptionsWithOptionsTemplate, OptionsWithOptionsTemplate,
} from 'plugins/optionsValidation/transformation'; } from 'plugins/optionsValidationPlugin/transformation';
type TestOptionsObj = { propA: 'propA'; null: null }; type TestOptionsObj = { propA: 'propA'; null: null };
type TestOptionsEnum = 'A' | 'B' | 'C'; type TestOptionsEnum = 'A' | 'B' | 'C';
@@ -2,7 +2,7 @@ import {
validateOptions, validateOptions,
optionsTemplateTypes as oTypes, optionsTemplateTypes as oTypes,
OptionsTemplate, OptionsTemplate,
} from 'plugins/optionsValidation/validation'; } from 'plugins/optionsValidationPlugin/validation';
import { assignDeep } from 'support/utils'; import { assignDeep } from 'support/utils';
type TestOptionsObj = { propA: 'propA'; null: null }; type TestOptionsObj = { propA: 'propA'; null: null };
@@ -0,0 +1,36 @@
import { addPlugin, getPlugins } from 'plugins';
describe('plugins', () => {
test('getPlugins', () => {
const plugins = getPlugins();
expect(plugins).toEqual({});
});
test('addPlugin single', () => {
const myPlugin = {};
const myPlugin2 = {};
addPlugin({
myPlugin,
myPlugin2,
});
const plugins = getPlugins();
expect(plugins.myPlugin).toBe(myPlugin);
expect(plugins.myPlugin2).toBe(undefined); // one plugin per object
});
test('addPlugin multiple', () => {
const myPlugin = {};
const myPlugin2 = {};
addPlugin([
{
myPlugin,
},
{
myPlugin2,
},
]);
const plugins = getPlugins();
expect(plugins.myPlugin).toBe(myPlugin);
expect(plugins.myPlugin2).toBe(myPlugin2);
});
});
@@ -1,4 +1,4 @@
import { hasClass, isFunction, isHTMLElement } from 'support'; import { hasClass, is, isFunction, isHTMLElement } from 'support';
import { dataAttributeHost } from 'classnames'; import { dataAttributeHost } from 'classnames';
import { InternalEnvironment } from 'environment'; import { InternalEnvironment } from 'environment';
import { import {
@@ -34,27 +34,42 @@ interface StructureSetupElementsProxy {
destroy: () => void; destroy: () => void;
} }
type TargetType = 'element' | 'textarea' | 'body';
const textareaId = 'textarea'; const textareaId = 'textarea';
const textareaHostId = 'host'; const textareaHostId = 'host';
const elementId = 'target'; const elementId = 'target';
const dynamicContent = 'text<p>paragraph</p>'; const dynamicContent = 'text<p>paragraph</p>';
const textareaContent = `<textarea id="${textareaId}">text</textarea>`; const textareaContent = `<textarea id="${textareaId}">text</textarea>`;
const getSnapshot = () => document.body.innerHTML; const getSnapshot = () => document.documentElement.outerHTML;
const getTarget = (textarea?: boolean) => const getTarget = (targetType: TargetType) => {
document.getElementById(textarea ? textareaId : elementId)!; switch (targetType) {
const fillBody = (textarea?: boolean, customDOM?: (content: string, hostId: string) => string) => { case 'element':
document.body.innerHTML = ` return document.getElementById(elementId)!;
case 'textarea':
return document.getElementById(textareaId)!;
case 'body':
return document.body;
default:
throw new Error('Invalid Target');
}
};
const fillBody = (
targetType: TargetType,
customDOM?: (content: string, hostId: string) => string
) => {
const textarea = targetType === 'textarea';
const customDomResult =
customDOM &&
customDOM(textarea ? textareaContent : dynamicContent, textarea ? textareaHostId : elementId);
const normalDom = textarea ? textareaContent : `<div id="${elementId}">${dynamicContent}</div>`;
document.body.innerHTML =
targetType === 'body'
? dynamicContent
: `
<nav></nav> <nav></nav>
${ ${customDomResult || normalDom}
customDOM
? customDOM(
textarea ? textareaContent : dynamicContent,
textarea ? textareaHostId : elementId
)
: textarea
? textareaContent
: `<div id="${elementId}">${dynamicContent}</div>`
}
<footer></footer> <footer></footer>
`; `;
return getSnapshot(); return getSnapshot();
@@ -63,8 +78,8 @@ const clearBody = () => {
document.body.innerHTML = ''; document.body.innerHTML = '';
}; };
const getElements = (textarea?: boolean) => { const getElements = (targetType: TargetType) => {
const target = getTarget(textarea); const target = getTarget(targetType);
const host = document.querySelector('[data-overlayscrollbars]')!; const host = document.querySelector('[data-overlayscrollbars]')!;
const padding = document.querySelector('.os-padding')!; const padding = document.querySelector('.os-padding')!;
const viewport = document.querySelector('.os-viewport')!; const viewport = document.querySelector('.os-viewport')!;
@@ -79,8 +94,8 @@ const getElements = (textarea?: boolean) => {
}; };
}; };
const assertCorrectDOMStructure = (textarea: boolean, viewportIsTarget: boolean) => { const assertCorrectDOMStructure = (targetType: TargetType, viewportIsTarget: boolean) => {
const { target, host, padding, viewport, content } = getElements(textarea); const { target, host, padding, viewport, content } = getElements(targetType);
if (viewportIsTarget) { if (viewportIsTarget) {
expect(target).toBe(host); expect(target).toBe(host);
@@ -100,12 +115,14 @@ const assertCorrectDOMStructure = (textarea: boolean, viewportIsTarget: boolean)
expect(padding.parentElement).toBe(host); expect(padding.parentElement).toBe(host);
} }
expect(host.parentElement).toBe(document.body); if (targetType !== 'body') {
expect(host.previousElementSibling).toBe(document.querySelector('nav')); expect(host.parentElement).toBe(document.body);
expect(host.nextElementSibling).toBe(document.querySelector('footer')); expect(host.previousElementSibling).toBe(document.querySelector('nav'));
expect(host.nextElementSibling).toBe(document.querySelector('footer'));
}
const contentElm = content || viewport; const contentElm = content || viewport;
if (textarea) { if (targetType === 'textarea') {
expect(target.parentElement).toBe(contentElm); expect(target.parentElement).toBe(contentElm);
expect(contentElm.innerHTML).toBe(textareaContent); expect(contentElm.innerHTML).toBe(textareaContent);
} else { } else {
@@ -128,7 +145,7 @@ const createStructureSetupProxy = (
}; };
const assertCorrectSetupElements = ( const assertCorrectSetupElements = (
textarea: boolean, targetType: TargetType,
setupElementsProxy: StructureSetupElementsProxy, setupElementsProxy: StructureSetupElementsProxy,
environment: InternalEnvironment environment: InternalEnvironment
): [StructureSetupElementsObj, () => void] => { ): [StructureSetupElementsObj, () => void] => {
@@ -143,11 +160,13 @@ const assertCorrectSetupElements = (
_viewportHasClass, _viewportHasClass,
_viewportAddRemoveClass, _viewportAddRemoveClass,
} = elements; } = elements;
const { target, host, padding, viewport, content } = getElements(textarea); const { target, host, padding, viewport, content } = getElements(targetType);
const isTextarea = target.matches('textarea'); const isTextarea = target.matches('textarea');
const isBody = target.matches('body'); const isBody = target.matches('body');
expect(textarea).toBe(isTextarea); if (targetType !== 'element') {
expect(target.matches(targetType)).toBe(true);
}
expect(_target).toBe(target); expect(_target).toBe(target);
expect(_host).toBe(host); expect(_host).toBe(host);
@@ -222,52 +241,36 @@ const assertCorrectSetupElements = (
if (input === undefined) { if (input === undefined) {
if (isStaticStrategy) { if (isStaticStrategy) {
strategy = strategy as StructureStaticInitializationElement; strategy = strategy as StructureStaticInitializationElement;
if (typeof strategy === 'function') { const resultingStrategy = typeof strategy === 'function' ? strategy(target) : strategy;
const result = strategy(target); if (_viewportIsTarget) {
if (_viewportIsTarget) { if (kind === 'host') {
if (kind === 'host') {
expect(elm).toBeTruthy();
} else {
expect(elm).toBeFalsy();
}
} else if (result && !isTextarea) {
expect(result).toBe(elm);
} else {
expect(elm).toBeTruthy(); expect(elm).toBeTruthy();
} else {
expect(elm).toBeFalsy();
} }
} else if (resultingStrategy && !isTextarea) {
expect(resultingStrategy).toBe(elm);
} else { } else {
expect(elm).toBeTruthy(); expect(elm).toBeTruthy();
} }
} else { } else {
strategy = strategy as StructureDynamicInitializationElement; strategy = strategy as StructureDynamicInitializationElement;
const resultingStrategy = typeof strategy === 'function' ? strategy(target) : strategy;
if (typeof strategy === 'function') { const resultIsBoolean = typeof resultingStrategy === 'boolean';
const result = strategy(target); if (_viewportIsTarget) {
const resultIsBoolean = typeof result === 'boolean'; if (kind === 'host') {
if (_viewportIsTarget) { expect(elm).toBeTruthy();
if (kind === 'host') { } else {
expect(elm).toBeTruthy(); expect(elm).toBeFalsy();
} else {
expect(elm).toBeFalsy();
}
} else if (resultIsBoolean) {
if (result) {
expect(elm).toBeTruthy();
} else {
expect(elm).toBeFalsy();
}
} else if (result) {
expect(elm).toBe(result);
} }
} else { } else if (resultIsBoolean) {
const strategyIsBoolean = typeof strategy === 'boolean'; if (resultingStrategy) {
if (strategyIsBoolean) { expect(elm).toBeTruthy();
if (strategy) { } else {
expect(elm).toBeTruthy(); expect(elm).toBeFalsy();
} else {
expect(elm).toBeFalsy();
}
} }
} else if (resultingStrategy) {
expect(elm).toBe(resultingStrategy);
} }
} }
} }
@@ -345,7 +348,7 @@ const envNativeScrollbarStyling = {
name: 'native scrollbar styling', name: 'native scrollbar styling',
env: { env: {
...env, ...env,
_nativeScrollbarStyling: true, _nativeScrollbarsHiding: true,
}, },
}; };
const envCssCustomProperties = { const envCssCustomProperties = {
@@ -359,11 +362,12 @@ const envInitStrategyMin = {
name: 'initialization strategy min', name: 'initialization strategy min',
env: { env: {
...env, ...env,
_getInitializationStrategy: () => ({ _getDefaultInitialization: () => ({
_host: null, ...env._staticDefaultInitialization,
_viewport: () => null, host: null,
_content: () => false, viewport: () => null,
_padding: false, content: () => false,
padding: false,
}), }),
}, },
}; };
@@ -371,11 +375,12 @@ const envInitStrategyMax = {
name: 'initialization strategy max', name: 'initialization strategy max',
env: { env: {
...env, ...env,
_getInitializationStrategy: () => ({ _getDefaultInitialization: () => ({
_host: null, ...env._staticDefaultInitialization,
_viewport: null, host: null,
_content: true, viewport: null,
_padding: () => true, content: true,
padding: () => true,
}), }),
}, },
}; };
@@ -383,21 +388,23 @@ const envInitStrategyAssigned = {
name: 'initialization strategy assigned', name: 'initialization strategy assigned',
env: { env: {
...env, ...env,
_getInitializationStrategy: () => ({ _getDefaultInitialization: () => ({
_host: () => document.querySelector('#host1') as HTMLElement, ...env._staticDefaultInitialization,
_viewport: (target: HTMLElement) => target.querySelector('#viewport') as HTMLElement, host: () => document.querySelector('#host1') as HTMLElement,
_content: (target: HTMLElement) => target.querySelector<HTMLElement>('#content'), viewport: (target: HTMLElement) => target.querySelector('#viewport') as HTMLElement,
_padding: (target: HTMLElement) => target.querySelector<HTMLElement>('#padding'), content: (target: HTMLElement) => target.querySelector<HTMLElement>('#content'),
padding: (target: HTMLElement) => target.querySelector<HTMLElement>('#padding'),
}), }),
}, },
}; };
const envInitStrategyViewportIsTarget = { const envInitStrategyViewportIsTarget = {
name: 'initialization strategy assigned', name: 'initialization strategy viewport is target',
env: { env: {
...env, ...env,
_nativeScrollbarStyling: true, _nativeScrollbarsHiding: true,
_getInitializationStrategy: () => ({ _getDefaultInitialization: () => ({
_viewport: (target: HTMLElement) => target, ...env._staticDefaultInitialization,
viewport: (target: HTMLElement) => !is(target, 'textarea') && target,
}), }),
}, },
}; };
@@ -420,28 +427,28 @@ describe('structureSetup', () => {
mockGetEnvironment.mockImplementation(() => currEnv); mockGetEnvironment.mockImplementation(() => currEnv);
}); });
[false, true].forEach((isTextarea) => { (['element', 'textarea', 'body'] as TargetType[]).forEach((targetType) => {
describe(isTextarea ? 'textarea' : 'element', () => { describe(targetType, () => {
describe('basic', () => { describe('basic', () => {
test('Element', () => { test('Element', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy(getTarget(isTextarea)), createStructureSetupProxy(getTarget(targetType)),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('Object', () => { test('Object', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ target: getTarget(isTextarea) }), createStructureSetupProxy({ target: getTarget(targetType) }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
@@ -450,58 +457,58 @@ describe('structureSetup', () => {
describe('single assigned', () => { describe('single assigned', () => {
test('padding', () => { test('padding', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding">${content}</div></div>` `<div id="${hostId}"><div id="padding">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => document.querySelector<HTMLElement>('#padding')!, padding: () => document.querySelector<HTMLElement>('#padding')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('viewport', () => { test('viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: () => document.querySelector<HTMLElement>('#host')!, host: () => document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('content', () => { test('content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="content">${content}</div></div>` `<div id="${hostId}"><div id="content">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
content: document.querySelector<HTMLElement>('#content')!, content: document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
@@ -509,176 +516,176 @@ describe('structureSetup', () => {
describe('multiple assigned', () => { describe('multiple assigned', () => {
test('padding viewport content', () => { test('padding viewport content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding"><div id="viewport"><div id="content">${content}</div></div></div></div>` `<div id="${hostId}"><div id="padding"><div id="viewport"><div id="content">${content}</div></div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: document.querySelector<HTMLElement>('#padding')!, padding: document.querySelector<HTMLElement>('#padding')!,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: () => document.querySelector<HTMLElement>('#content')!, content: () => document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('padding viewport', () => { test('padding viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>` `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: () => document.querySelector<HTMLElement>('#host')!, host: () => document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: document.querySelector<HTMLElement>('#padding')!, padding: document.querySelector<HTMLElement>('#padding')!,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('padding content', () => { test('padding content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding"><div id="content">${content}</div></div></div>` `<div id="${hostId}"><div id="padding"><div id="content">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => document.querySelector<HTMLElement>('#padding')!, padding: () => document.querySelector<HTMLElement>('#padding')!,
content: document.querySelector<HTMLElement>('#content')!, content: document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('viewport content', () => { test('viewport content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>` `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: () => document.querySelector<HTMLElement>('#content')!, content: () => document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
describe('single false', () => { describe('single false', () => {
test('padding', () => { test('padding', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
padding: false, padding: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('content', () => { test('content', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
content: () => false, content: () => false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
describe('single true', () => { describe('single true', () => {
test('padding', () => { test('padding', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => true, padding: () => true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('content', () => { test('content', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
describe('multiple false', () => { describe('multiple false', () => {
test('padding & content', () => { test('padding & content', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
padding: false, padding: false,
content: false, content: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
describe('multiple true', () => { describe('multiple true', () => {
test('padding & content', () => { test('padding & content', () => {
const snapshot = fillBody(isTextarea); const snapshot = fillBody(targetType);
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
target: getTarget(isTextarea), target: getTarget(targetType),
padding: true, padding: true,
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
@@ -686,329 +693,329 @@ describe('structureSetup', () => {
describe('mixed', () => { describe('mixed', () => {
test('false: padding & content | assigned: viewport', () => { test('false: padding & content | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: false, padding: false,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: false, content: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: padding & content | assigned: viewport', () => { test('true: padding & content | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: true, padding: true,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: content | false: padding | assigned: viewport', () => { test('true: content | false: padding | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => false, padding: () => false,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: () => true, content: () => true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: padding | false: content | assigned: viewport', () => { test('true: padding | false: content | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: true, padding: true,
viewport: () => document.querySelector<HTMLElement>('#viewport')!, viewport: () => document.querySelector<HTMLElement>('#viewport')!,
content: false, content: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: padding | assigned: content', () => { test('false: padding | assigned: content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="content">${content}</div></div>` `<div id="${hostId}"><div id="content">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: false, padding: false,
content: document.querySelector<HTMLElement>('#content')!, content: document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: padding | assigned: content', () => { test('true: padding | assigned: content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="content">${content}</div></div>` `<div id="${hostId}"><div id="content">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: true, padding: true,
content: document.querySelector<HTMLElement>('#content')!, content: document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: padding | assigned: viewport', () => { test('false: padding | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => false, padding: () => false,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: padding | assigned: viewport', () => { test('true: padding | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: true, padding: true,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: padding | assigned: viewport & content', () => { test('false: padding | assigned: viewport & content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>` `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
padding: false, padding: false,
content: () => document.querySelector<HTMLElement>('#content')!, content: () => document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: padding | assigned: viewport & content', () => { test('true: padding | assigned: viewport & content', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>` `<div id="${hostId}"><div id="viewport"><div id="content">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: () => document.querySelector<HTMLElement>('#viewport')!, viewport: () => document.querySelector<HTMLElement>('#viewport')!,
padding: true, padding: true,
content: document.querySelector<HTMLElement>('#content')!, content: document.querySelector<HTMLElement>('#content')!,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: content | assigned: padding', () => { test('false: content | assigned: padding', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding">${content}</div></div>` `<div id="${hostId}"><div id="padding">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: document.querySelector<HTMLElement>('#padding')!, padding: document.querySelector<HTMLElement>('#padding')!,
content: false, content: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: content | assigned: padding', () => { test('true: content | assigned: padding', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding">${content}</div></div>` `<div id="${hostId}"><div id="padding">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: () => document.querySelector<HTMLElement>('#host')!, host: () => document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: document.querySelector<HTMLElement>('#padding')!, padding: document.querySelector<HTMLElement>('#padding')!,
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: content | assigned: viewport', () => { test('false: content | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: () => document.querySelector<HTMLElement>('#viewport')!, viewport: () => document.querySelector<HTMLElement>('#viewport')!,
content: false, content: false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: content | assigned: viewport', () => { test('true: content | assigned: viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="viewport">${content}</div></div>` `<div id="${hostId}"><div id="viewport">${content}</div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('false: content | assigned: padding & viewport', () => { test('false: content | assigned: padding & viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>` `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: document.querySelector<HTMLElement>('#host')!, host: document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: () => document.querySelector<HTMLElement>('#padding')!, padding: () => document.querySelector<HTMLElement>('#padding')!,
viewport: document.querySelector<HTMLElement>('#viewport')!, viewport: document.querySelector<HTMLElement>('#viewport')!,
content: () => false, content: () => false,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
test('true: content | assigned: padding & viewport', () => { test('true: content | assigned: padding & viewport', () => {
const snapshot = fillBody( const snapshot = fillBody(
isTextarea, targetType,
(content, hostId) => (content, hostId) =>
`<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>` `<div id="${hostId}"><div id="padding"><div id="viewport">${content}</div></div></div>`
); );
const [elements, destroy] = assertCorrectSetupElements( const [elements, destroy] = assertCorrectSetupElements(
isTextarea, targetType,
createStructureSetupProxy({ createStructureSetupProxy({
host: () => document.querySelector<HTMLElement>('#host')!, host: () => document.querySelector<HTMLElement>('#host')!,
target: getTarget(isTextarea), target: getTarget(targetType),
padding: document.querySelector<HTMLElement>('#padding')!, padding: document.querySelector<HTMLElement>('#padding')!,
viewport: () => document.querySelector<HTMLElement>('#viewport')!, viewport: () => document.querySelector<HTMLElement>('#viewport')!,
content: true, content: true,
}), }),
currEnv currEnv
); );
assertCorrectDOMStructure(isTextarea, elements._viewportIsTarget); assertCorrectDOMStructure(targetType, elements._viewportIsTarget);
assertCorrectDestroy(snapshot, destroy); assertCorrectDestroy(snapshot, destroy);
}); });
}); });
@@ -1,7 +1,6 @@
import { isEmptyObject } from 'support/utils/object'; import { isEmptyObject } from 'support/utils/object';
import { isString, isPlainObject } from 'support/utils/types'; import { isString, isPlainObject } from 'support/utils/types';
import { style, hide, show, topRightBottomLeft } from 'support/dom/style'; import { style, hide, show, topRightBottomLeft, directionIsRTL } from 'support/dom/style';
import { StyleObject } from 'typings';
describe('dom style', () => { describe('dom style', () => {
afterEach(() => { afterEach(() => {
@@ -36,8 +35,6 @@ describe('dom style', () => {
style(document.body, { width: '123px' }); style(document.body, { width: '123px' });
expect(document.body.style.width).toBe('123px'); expect(document.body.style.width).toBe('123px');
interface O {}
expect(document.body.style.getPropertyValue('--custom')).toBe(''); expect(document.body.style.getPropertyValue('--custom')).toBe('');
style<'--custom'>(document.body, { '--custom': '123px' }); style<'--custom'>(document.body, { '--custom': '123px' });
expect(document.body.style.getPropertyValue('--custom')).toBe('123px'); expect(document.body.style.getPropertyValue('--custom')).toBe('123px');
@@ -62,7 +59,13 @@ describe('dom style', () => {
expect(document.body.style.zIndex).toBe(''); expect(document.body.style.zIndex).toBe('');
expect(document.body.style.lineHeight).toBe(''); expect(document.body.style.lineHeight).toBe('');
expect(document.body.style.getPropertyValue('--custom')).toBe(''); expect(document.body.style.getPropertyValue('--custom')).toBe('');
style<'--custom'>(document.body, { width: '123px', height: 321, opacity: '0.5', zIndex: 1, '--custom': '123px' }); style<'--custom'>(document.body, {
width: '123px',
height: 321,
opacity: '0.5',
zIndex: 1,
'--custom': '123px',
});
expect(document.body.style.width).toBe('123px'); expect(document.body.style.width).toBe('123px');
expect(document.body.style.height).toBe('321px'); expect(document.body.style.height).toBe('321px');
expect(document.body.style.opacity).toBe('0.5'); expect(document.body.style.opacity).toBe('0.5');
@@ -138,4 +141,18 @@ describe('dom style', () => {
}); });
}); });
}); });
describe('directionIsRTL', () => {
test('normal', () => {
document.body.setAttribute('style', 'direction: rtl');
expect(directionIsRTL(document.body)).toBe(true);
document.body.setAttribute('style', 'direction: ltr');
expect(directionIsRTL(document.body)).toBe(false);
});
test('null', () => {
expect(directionIsRTL(null)).toBe(false);
});
});
}); });
@@ -1,7 +1,18 @@
import { find, findFirst, is, children, contents, parent, createDiv, liesBetween, createDOM } from 'support/dom'; import {
find,
findFirst,
is,
children,
contents,
parent,
createDiv,
liesBetween,
createDOM,
} from 'support/dom';
const slotElm = document.body; const slotElm = document.body;
const testHTML = '<div id="parent" class="div-class"><div id="child" class="div-class"></div></div><p>2</p><input type="text" value="3"></input>abc'; const testHTML =
'<div id="parent" class="div-class"><div id="child" class="div-class"></div></div><p>2</p><input type="text" value="3"></input>abc';
describe('dom traversal', () => { describe('dom traversal', () => {
beforeEach(() => { beforeEach(() => {
@@ -225,10 +236,18 @@ describe('dom traversal', () => {
}); });
describe('liesBetween', () => { describe('liesBetween', () => {
const elmsBetween = ['.host', '.something', '.something-a', '.something-b', '.padding', '.viewport', '.content']; const elmsBetween = [
'.host',
'.something',
'.something-a',
'.something-b',
'.padding',
'.viewport',
'.content',
];
const elmsOutside = ['.allowed-a', '.allowed-b', '.allowed-c', '.deeper-a', '.deeper-b']; const elmsOutside = ['.allowed-a', '.allowed-b', '.allowed-c', '.deeper-a', '.deeper-b'];
const elmsToTest = [...elmsBetween, ...elmsOutside]; const elmsToTest = [...elmsBetween, ...elmsOutside];
const domPart = (id: string, content?: string) => ` const nestedDomPart = (id: string, content?: string) => `
<div id="${id}" class="host"> <div id="${id}" class="host">
<div class="something"> <div class="something">
<div class="something-a"> <div class="something-a">
@@ -244,17 +263,39 @@ describe('dom traversal', () => {
</div> </div>
</div> </div>
</div> </div>
</div> </div>`;
`; const createNestedTestDOM = (nestings = 0) => {
const createTestDOM = (nestings = 0) => {
let part = ''; let part = '';
for (let i = 0; i < nestings + 1; i++) { for (let i = 0; i < nestings + 1; i++) {
part = domPart(`host-${nestings - i}`, part); part = nestedDomPart(`host-${nestings - i}`, part);
} }
return part; return part;
}; };
const genericTest = (nestings: number) => { const createSpecialTestDOM = () => `
<div class="host">
<div class="allowed-a">
<div class="allowed-b">
<div class="allowed-c">
</div>
</div>
</div>
<div class="host">
<div class="something">
<div class="something-a">
</div>
</div>
<div class="padding">
<div class="something-b"></div>
<div class="viewport">
<div class="content">
<div class="deeper-a"><div class="deeper-b"></div></div>
</div>
</div>
</div>
</div>
</div>`;
const genericTest = (nestings = 0) => {
const allHostIds = Array(nestings) const allHostIds = Array(nestings)
.fill(0) .fill(0)
.map((_, index) => `#host-${index}`); .map((_, index) => `#host-${index}`);
@@ -263,11 +304,19 @@ describe('dom traversal', () => {
const runExpectance = (id: string) => { const runExpectance = (id: string) => {
const isRemainingId = remainingIds.includes(id); const isRemainingId = remainingIds.includes(id);
elmsToTest.forEach((elm) => { elmsToTest.forEach((elm) => {
const hostElm = findFirst(`${id}`); const hostElm = findFirst(`${id}`) as HTMLElement;
const searchElm = hostElm?.classList.contains(elm.substring(1)) ? hostElm : findFirst(`${id} ${elm}`); const searchElm = hostElm?.classList.contains(elm.substring(1))
? hostElm
: findFirst(`${id} ${elm}`);
expect(liesBetween(searchElm, `${hostId}`, '.content')).toBe( expect(liesBetween(searchElm, `${hostId}`, '.content')).toBe(
isRemainingId ? false : elmsBetween.includes(elm) ? true : elmsOutside.includes(elm) ? false : undefined isRemainingId
? false
: elmsBetween.includes(elm)
? true
: elmsOutside.includes(elm)
? false
: undefined
); );
}); });
}; };
@@ -295,24 +344,32 @@ describe('dom traversal', () => {
} }
}; };
test('with native closest', () => { test('nested with native closest', () => {
slotElm.innerHTML = createTestDOM(3); slotElm.innerHTML = createNestedTestDOM(3);
genericTest(3); genericTest(3);
}); });
test('with polyfill closest', () => { test('nested with polyfill closest', () => {
const original = Element.prototype.closest; const original = Element.prototype.closest;
// @ts-ignore // @ts-ignore
Element.prototype.closest = undefined; Element.prototype.closest = undefined;
slotElm.innerHTML = createTestDOM(3); slotElm.innerHTML = createNestedTestDOM(3);
genericTest(3); genericTest(3);
Element.prototype.closest = original; Element.prototype.closest = original;
}); });
test('special with polyfill closest', () => {
slotElm.innerHTML = createSpecialTestDOM();
genericTest();
});
test('text node', () => { test('text node', () => {
expect(liesBetween(createDOM('<div>textnodehere</div>')[0].firstChild, '.a', '.b')).toEqual(false); slotElm.innerHTML = createNestedTestDOM(3);
expect(liesBetween(createDOM('<div>textnodehere</div>')[0].firstChild, '.a', '.b')).toEqual(
false
);
}); });
}); });
}); });