Skip to content

Commit b9d975e

Browse files
committed
refactor: simplify DOM utils with modern code logic
1 parent ba7a129 commit b9d975e

3 files changed

Lines changed: 42 additions & 46 deletions

File tree

packages/common/src/extensions/menuBaseClass.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,10 @@ export class MenuBaseClass<M extends MenuPlugin | HeaderButton | ColumnPicker |
897897
dropOffset = Number((addonOptions as CellMenu | ContextMenu)?.autoAdjustDropOffset || 0);
898898
sideOffset = Number((addonOptions as CellMenu | ContextMenu)?.autoAlignSideOffset || 0);
899899
} else {
900-
menuOffsetLeft = isSubMenu ? parentOffset.left : (relativePos?.left ?? 0);
900+
menuOffsetLeft = isSubMenu ? parentOffset.left : relativePos.left;
901901
menuOffsetTop = isSubMenu
902902
? parentOffset.top
903-
: (relativePos?.top ?? 0) + ((addonOptions as HeaderMenuOption)?.menuOffsetTop ?? 0) + targetElm.clientHeight;
903+
: relativePos.top + ((addonOptions as HeaderMenuOption)?.menuOffsetTop ?? 0) + targetElm.clientHeight;
904904
}
905905

906906
if ((this.pluginName === 'ContextMenu' || this.pluginName === 'GridMenu') && isSubMenu) {

packages/utils/src/__tests__/domUtils.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,9 @@ describe('Service/domUtilies', () => {
224224
parentDiv.innerHTML = `<span></span>`;
225225
document.body.appendChild(parentDiv);
226226

227-
it('should return undefined when element if not a valid html element', () => {
227+
it('should return element position of all zeros when element if not a valid html element', () => {
228228
const output = getOffsetRelativeToParent(null, null);
229-
expect(output).toEqual(undefined);
229+
expect(output).toEqual({ top: 0, left: 0, bottom: 0, right: 0 });
230230
});
231231

232232
it('should return top/left 0 when creating a new element in the document without positions', () => {
@@ -250,7 +250,7 @@ describe('Service/domUtilies', () => {
250250
div.innerHTML = `<span></span>`;
251251
document.body.appendChild(div);
252252

253-
it('should return undefined when element if not a valid html element', () => {
253+
it('should return element position of all zeros when element if not a valid html element', () => {
254254
const output = getOffset(null as any);
255255
expect(output).toEqual({ top: 0, bottom: 0, left: 0, right: 0 });
256256
});

packages/utils/src/domUtils.ts

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ export type CSSStyleDeclarationWritable = Omit<CSSStyleDeclaration, CSSStyleDecl
1414

1515
/** Calculate available space for each side of the DOM element */
1616
export function calculateAvailableSpace(element: HTMLElement): { top: number; bottom: number; left: number; right: number } {
17-
const vh = window.innerHeight || 0;
18-
const vw = window.innerWidth || 0;
17+
const vh = window.innerHeight;
18+
const vw = window.innerWidth;
1919
const { top: pageScrollTop, left: pageScrollLeft } = windowScrollPosition();
20-
const { top: elementOffsetTop = 0, left: elementOffsetLeft = 0 } = getOffset(element) || {};
20+
const { top: elementOffsetTop = 0, left: elementOffsetLeft = 0 } = getOffset(element) ?? {};
2121

2222
const top = elementOffsetTop - pageScrollTop;
2323
const left = elementOffsetLeft - pageScrollLeft;
@@ -131,27 +131,23 @@ export function getHtmlStringOutput(
131131
): string {
132132
if (input instanceof DocumentFragment) {
133133
// a DocumentFragment doesn't have innerHTML/outerHTML, but we can loop through all children and concatenate them all to an HTML string
134-
return [].map.call(input.childNodes, (x: HTMLElement) => x[type]).join('') || input.textContent || '';
134+
return (
135+
Array.from(input.childNodes)
136+
.map((node: ChildNode) => (node as HTMLElement)[type])
137+
.join('') ||
138+
input.textContent ||
139+
''
140+
);
135141
} else if (input instanceof HTMLElement) {
136142
return input[type];
137143
}
138-
return String(input ?? ''); // reaching this line means it's already a string (or number) so just return it as string
144+
return String(input ?? '');
139145
}
140146

141147
/** Get offset of HTML element relative to a parent element */
142-
export function getOffsetRelativeToParent(
143-
parentElm: HTMLElement | null,
144-
childElm: HTMLElement | null
145-
):
146-
| {
147-
top: number;
148-
right: number;
149-
bottom: number;
150-
left: number;
151-
}
152-
| undefined {
148+
export function getOffsetRelativeToParent(parentElm: HTMLElement | null, childElm: HTMLElement | null): HtmlElementPosition {
153149
if (!parentElm || !childElm) {
154-
return undefined;
150+
return { top: 0, bottom: 0, left: 0, right: 0 };
155151
}
156152
const parentPos = parentElm.getBoundingClientRect();
157153
const childPos = childElm.getBoundingClientRect();
@@ -165,7 +161,7 @@ export function getOffsetRelativeToParent(
165161

166162
/** Get HTML element offset with pure JS */
167163
export function getOffset(elm?: HTMLElement | null): HtmlElementPosition {
168-
if (!elm?.getBoundingClientRect) {
164+
if (!elm) {
169165
return { top: 0, bottom: 0, left: 0, right: 0 };
170166
}
171167

@@ -195,10 +191,10 @@ export function getInnerSize(elm: HTMLElement, type: 'height' | 'width'): number
195191

196192
/** Get a DOM element style property value by calling getComputedStyle() on the element */
197193
export function getStyleProp(elm: HTMLElement, property: string): string | null {
198-
if (elm) {
199-
return getComputedStyle(elm).getPropertyValue(property);
194+
if (!elm) {
195+
return null;
200196
}
201-
return null;
197+
return getComputedStyle(elm).getPropertyValue(property);
202198
}
203199

204200
export function findFirstAttribute(inputElm: Element | null | undefined, attributes: string[]): string | null {
@@ -223,24 +219,6 @@ export function findWidthOrDefault(inputWidth?: number | string | null, defaultV
223219
return (/^[0-9]+$/i.test(`${inputWidth}`) ? `${+(inputWidth as number)}px` : (inputWidth as string)) || defaultValue;
224220
}
225221

226-
/**
227-
* Simple function to encode the 5 most common HTML entities (`<`, `>`, `"`, `'`, `&`).
228-
* For example: "<div>Hello</div>" => "&lt;div&gt;Hello&lt;/div&gt;"
229-
* @param {String} inputValue - input value to be encoded
230-
* @return {String}
231-
*/
232-
export function htmlEncode(inputValue: string): string {
233-
const val = typeof inputValue === 'string' ? inputValue : String(inputValue);
234-
const entityMap: { [char: string]: string } = {
235-
'&': '&amp;',
236-
'<': '&lt;',
237-
'>': '&gt;',
238-
'"': '&quot;',
239-
"'": '&#39;',
240-
};
241-
return (val || '').toString().replace(/[&<>"']/g, (s) => entityMap[s as keyof { [char: string]: string }]);
242-
}
243-
244222
/**
245223
* Simple function to decode the most common HTML entities.
246224
* For example: "&lt;div&gt;Hablar espa&#241;ol? &#55358;&#56708;&lt;/div&gt;" => "<div>Hablar español? 🦄</div>"
@@ -280,6 +258,24 @@ export function htmlDecode(input?: string | boolean | number): string {
280258
return '';
281259
}
282260

261+
/**
262+
* Simple function to encode the 5 most common HTML entities (`<`, `>`, `"`, `'`, `&`).
263+
* For example: "<div>Hello</div>" => "&lt;div&gt;Hello&lt;/div&gt;"
264+
* @param {String} inputValue - input value to be encoded
265+
* @return {String}
266+
*/
267+
export function htmlEncode(inputValue: string): string {
268+
const val = typeof inputValue === 'string' ? inputValue : String(inputValue);
269+
const entityMap: { [char: string]: string } = {
270+
'&': '&amp;',
271+
'<': '&lt;',
272+
'>': '&gt;',
273+
'"': '&quot;',
274+
"'": '&#39;',
275+
};
276+
return (val || '').toString().replace(/[&<>"']/g, (s) => entityMap[s as keyof { [char: string]: string }]);
277+
}
278+
283279
/**
284280
* Encode string to html special char and add html space padding defined
285281
* @param {string} inputStr - input string
@@ -308,7 +304,7 @@ export function insertAfterElement(referenceNode: HTMLElement, newNode: HTMLElem
308304
*/
309305
export function windowScrollPosition(): { left: number; top: number } {
310306
return {
311-
left: window.pageXOffset || document.documentElement.scrollLeft || 0,
312-
top: window.pageYOffset || document.documentElement.scrollTop || 0,
307+
left: window.pageXOffset,
308+
top: window.pageYOffset,
313309
};
314310
}

0 commit comments

Comments
 (0)