add box-sizing change detection to size observer

This commit is contained in:
Rene
2021-04-21 22:48:15 +02:00
parent 2f51abe081
commit 235cf73c1d
10 changed files with 299 additions and 103 deletions
@@ -2,17 +2,24 @@ import 'styles/overlayscrollbars.scss';
import './index.scss';
import { resize } from '@/testing-browser/Resize';
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
import { OverlayScrollbars } from 'overlayscrollbars';
import { style } from 'support';
import { from, style } from 'support';
const targetElm = document.querySelector('#target') as HTMLElement;
const osInstance = (window.os = OverlayScrollbars({ target: targetElm, content: false }));
const osInstance = (window.os = OverlayScrollbars({ target: targetElm, content: true }));
const target: HTMLElement | null = document.querySelector('#target');
const comparison: HTMLElement | null = document.querySelector('#comparison');
const targetRes: HTMLElement | null = document.querySelector('#target .resize');
const comparisonRes: HTMLElement | null = document.querySelector('#comparison .resize');
const resizeElms = document.querySelectorAll('.resize');
const percentElms = document.querySelectorAll('.percent');
const endElms = document.querySelectorAll('.end');
const envElms = document.querySelectorAll<HTMLElement>('.env');
const containerElms = document.querySelectorAll<HTMLElement>('#target, #comparison');
resize(target!).addResizeListener((width, height) => style(comparison, { width, height }));
//resize(comparison!).addResizeListener((width, height) => style(target, { width, height }));
resize(targetRes!).addResizeListener((width, height) => style(comparisonRes, { width, height }));
@@ -23,3 +30,41 @@ target!.querySelector('.os-viewport')?.addEventListener('scroll', (e) => {
comparison!.scrollLeft = viewport.scrollLeft;
comparison!.scrollTop = viewport.scrollTop;
});
const envWidthSelect = document.querySelector<HTMLSelectElement>('#envWidth');
const envHeightSelect = document.querySelector<HTMLSelectElement>('#envHeight');
const selectCallbackEnv = generateClassChangeSelectCallback(from(envElms));
const containerWidthSelect = document.querySelector<HTMLSelectElement>('#width');
const containerHeightSelect = document.querySelector<HTMLSelectElement>('#height');
const containerFloatSelect = document.querySelector<HTMLSelectElement>('#float');
const containerPaddingSelect = document.querySelector<HTMLSelectElement>('#padding');
const containerBorderSelect = document.querySelector<HTMLSelectElement>('#border');
const containerMarginSelect = document.querySelector<HTMLSelectElement>('#margin');
const containerBoxSizingSelect = document.querySelector<HTMLSelectElement>('#boxSizing');
const containerDirectionSelect = document.querySelector<HTMLSelectElement>('#direction');
const containerMinMaxSelect = document.querySelector<HTMLSelectElement>('#minMax');
const selectCallbackContainer = generateClassChangeSelectCallback(from(containerElms));
envWidthSelect?.addEventListener('change', selectCallbackEnv);
envHeightSelect?.addEventListener('change', selectCallbackEnv);
containerWidthSelect?.addEventListener('change', selectCallbackContainer);
containerHeightSelect?.addEventListener('change', selectCallbackContainer);
containerFloatSelect?.addEventListener('change', selectCallbackContainer);
containerPaddingSelect?.addEventListener('change', selectCallbackContainer);
containerBorderSelect?.addEventListener('change', selectCallbackContainer);
containerMarginSelect?.addEventListener('change', selectCallbackContainer);
containerBoxSizingSelect?.addEventListener('change', selectCallbackContainer);
containerDirectionSelect?.addEventListener('change', selectCallbackContainer);
containerMinMaxSelect?.addEventListener('change', selectCallbackContainer);
selectCallbackEnv(envWidthSelect);
selectCallbackEnv(envHeightSelect);
selectCallbackContainer(containerWidthSelect);
selectCallbackContainer(containerHeightSelect);
selectCallbackContainer(containerFloatSelect);
selectCallbackContainer(containerPaddingSelect);
selectCallbackContainer(containerBorderSelect);
selectCallbackContainer(containerMarginSelect);
selectCallbackContainer(containerBoxSizingSelect);
selectCallbackContainer(containerDirectionSelect);
selectCallbackContainer(containerMinMaxSelect);
@@ -1,6 +1,6 @@
<div id="controls">
<label for="evnHeight">evnHeight</label>
<select name="evnHeight" id="evnHeight">
<label for="envHeight">envHeight</label>
<select name="envHeight" id="envHeight">
<option value="envHeightAuto">auto</option>
<option value="envHeightHundred">100%</option>
</select>
@@ -35,9 +35,9 @@
</select>
<label for="border">border</label>
<select name="border" id="border">
<option value="borderNone">none</option>
<option value="borderSmall">small</option>
<option value="borderLarge">large</option>
<option value="borderNone">none</option>
</select>
<label for="margin">margin</label>
<select name="margin" id="margin">
@@ -50,11 +50,6 @@
<option value="boxSizingBorderBox">border-box</option>
<option value="boxSizingContentBox">content-box</option>
</select>
<label for="display">display</label>
<select name="display" id="display">
<option value="displayBlock">block</option>
<option value="displayNone">none</option>
</select>
<label for="direction">direction</label>
<select name="direction" id="direction">
<option value="directionLTR">ltr</option>
@@ -36,21 +36,45 @@ body {
.column {
width: 100%;
height: 100%;
font-size: 0;
line-height: 0;
}
.env {
background: rgba(0, 0, 0, 0.1);
}
#target,
#comparison {
position: relative;
border: 2px solid red;
min-height: 100px;
min-width: 200px;
max-height: 300px;
max-width: 320px;
padding: 5px 50px 15px 20px;
.os-viewport::before,
&::before {
content: '';
display: block;
position: absolute;
border: 2px dotted red;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
pointer-events: none;
}
* {
font-size: medium;
line-height: normal;
}
}
#target::before {
opacity: 0.3;
}
#comparison {
overflow: hidden;
z-index: 0;
}
.resize {
@@ -73,7 +97,6 @@ body {
border: 1px solid black;
padding: 10px;
margin: 10px;
display: none;
}
.end::before {
@@ -89,68 +112,6 @@ body {
opacity: 0.5;
}
.padding0 {
padding: 0;
}
.padding10 {
padding: 10px;
}
.padding50 {
padding: 50px;
}
.border2 {
border: 2px solid red;
}
.border10 {
border: 10px solid red;
}
.border0 {
border: none;
}
.heightAuto {
height: auto;
}
.height200 {
height: 200px;
}
.heightHundred {
height: 100%;
}
.widthAuto {
width: auto;
float: left;
}
.width200 {
width: 200px;
}
.widthHundred {
width: 100%;
}
.boxSizingBorderBox {
box-sizing: border-box;
}
.boxSizingContentBox {
box-sizing: content-box;
}
.displayNone {
display: none;
}
.displayBlock {
display: block;
}
.directionltr {
direction: ltr;
}
.directionRTL {
direction: rtl;
}
.resizer {
position: relative;
}
@@ -165,6 +126,117 @@ body {
opacity: 0.3;
}
.widthAuto,
.envWidthAuto {
width: auto;
display: inline-block;
}
#target.widthAuto {
display: inline-flex;
}
.widthHundred,
.envWidthHundred {
width: 100%;
}
.heightAuto,
.envHeightAuto {
height: auto;
}
.heightHundred,
.envHeightHundred {
height: 100%;
}
.width200 {
width: 200px;
}
.height200 {
height: 200px;
}
.floatNone {
float: none;
}
.floatLeft {
float: left;
}
.floatRight {
float: right;
}
.paddingNone {
padding: 0;
}
.paddingSmall {
padding: 5px 50px 15px 20px;
}
.paddingLarge {
padding: 12px 22px 53px 33px;
}
.borderNone {
border: none;
}
.borderSmall {
border-color: darkorange;
border-style: solid;
border-width: 2px 5px 3px 4px;
}
.borderLarge {
border-color: darkorange;
border-style: solid;
border-width: 9px 6px 7px 3px;
}
.marginNone {
margin: 0;
}
.marginSmall {
margin: 21px 16px 4px 33px;
}
.marginLarge {
margin: 33px 46px 69px 23px;
}
.boxSizingBorderBox {
box-sizing: border-box;
}
.boxSizingContentBox {
box-sizing: content-box;
}
.directionLTR {
direction: ltr;
}
.directionRTL {
direction: rtl;
}
.minMaxFixed {
min-height: 180px;
min-width: 180px;
max-height: 420px;
max-width: 420px;
}
.minMaxNone {
min-height: 0;
min-width: 0;
max-height: none;
max-width: none;
}
/*
.os-environment::-webkit-scrollbar,
.os-viewport::-webkit-scrollbar,
@@ -2,7 +2,7 @@ import 'styles/overlayscrollbars.scss';
import './index.scss';
import './handleEnvironment';
import should from 'should';
import { generateClassChangeSelectCallback, iterateSelect } from '@/testing-browser/Select';
import { generateClassChangeSelectCallback, iterateSelect, selectOption } from '@/testing-browser/Select';
import { setTestResult, waitForOrFailTest } from '@/testing-browser/TestResult';
import { timeout } from '@/testing-browser/timeout';
import { hasDimensions, offsetSize, WH, style } from 'support';
@@ -60,6 +60,7 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
currOffsetSize: WH<number>;
currContentSize: WH<number>;
currDir: string;
currBoxSizing: string;
}
await iterateSelect<IterateSelect>(select, {
@@ -69,6 +70,7 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
const currOffsetSize = offsetSize(targetElm as HTMLElement);
const currContentSize = contentBox(targetElm as HTMLElement);
const currDir = style(targetElm as HTMLElement, 'direction');
const currBoxSizing = style(targetElm as HTMLElement, 'box-sizing');
return {
currSizeIterations,
@@ -76,15 +78,18 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
currOffsetSize,
currContentSize,
currDir,
currBoxSizing,
};
},
async check({ currSizeIterations, currDirectionIterations, currOffsetSize, currContentSize, currDir }) {
async check({ currSizeIterations, currDirectionIterations, currOffsetSize, currContentSize, currDir, currBoxSizing }) {
const newOffsetSize = offsetSize(targetElm as HTMLElement);
const newContentSize = contentBox(targetElm as HTMLElement);
const newDir = style(targetElm as HTMLElement, 'direction');
const newBoxSizing = style(targetElm as HTMLElement, 'box-sizing');
const offsetSizeChanged = currOffsetSize.w !== newOffsetSize.w || currOffsetSize.h !== newOffsetSize.h;
const contentSizeChanged = currContentSize.w !== newContentSize.w || currContentSize.h !== newContentSize.h;
const dirChanged = currDir !== newDir;
const boxSizingChanged = currBoxSizing !== newBoxSizing;
const dimensions = hasDimensions(targetElm as HTMLElement);
const observerElm = targetElm?.firstElementChild as HTMLElement;
@@ -102,9 +107,9 @@ const iterate = async (select: HTMLSelectElement | null, afterEach?: () => any)
);
}
if (dimensions && (offsetSizeChanged || contentSizeChanged || dirChanged)) {
if (dimensions && (offsetSizeChanged || contentSizeChanged || dirChanged || boxSizingChanged)) {
await waitForOrFailTest(() => {
if (offsetSizeChanged || contentSizeChanged) {
if (offsetSizeChanged || contentSizeChanged || boxSizingChanged) {
should.equal(sizeIterations, currSizeIterations + 1, 'Size change was detected correctly.');
}
if (dirChanged) {
@@ -159,6 +164,36 @@ const iterateDisplay = async (afterEach?: () => any) => {
const iterateDirection = async (afterEach?: () => any) => {
await iterate(directionSelect, afterEach);
};
const cleanBoxSizingChange = async () => {
selectOption(heightSelect as HTMLSelectElement, 'heightAuto');
selectOption(widthSelect as HTMLSelectElement, 'widthAuto');
selectOption(paddingSelect as HTMLSelectElement, 'padding0');
selectOption(borderSelect as HTMLSelectElement, 'border0');
await timeout(250);
await iterateDirection(async () => {
await iterateBoxSizing();
});
selectOption(heightSelect as HTMLSelectElement, 'height200');
selectOption(widthSelect as HTMLSelectElement, 'width200');
await timeout(250);
await iterateDirection(async () => {
await iterateBoxSizing();
});
selectOption(heightSelect as HTMLSelectElement, 'heightHundred');
selectOption(widthSelect as HTMLSelectElement, 'widthHundred');
await timeout(250);
await iterateDirection(async () => {
await iterateBoxSizing();
});
};
const start = async () => {
setTestResult(null);
@@ -180,6 +215,7 @@ const start = async () => {
});
});
});
await cleanBoxSizingChange();
sizeObserver._destroy();
should.equal(targetElm?.children.length, preInitChildren, 'Destruction removes all generated elements.');
@@ -34,6 +34,7 @@ body {
// prevent container from reaching 0x0 dimensions for testing purposes
min-width: 50px;
min-height: 50px;
background: rgba(0, 0, 0, 0.1);
}
.padding0 {