Tidy up the full frontend codebase and use optional chaining where possible (#620)

* Tidy up the full frontend codebase and use optional chaining where possible

* Code review changes
This commit is contained in:
Keavon Chambers
2022-04-30 02:52:53 -07:00
parent d1c32ad7d0
commit 8c9caf12c7
28 changed files with 640 additions and 622 deletions
@@ -161,13 +161,13 @@ export default defineComponent({
},
onPointerDown(e: PointerEvent) {
const saturationPicker = this.$refs.saturationPicker as typeof LayoutCol;
const saturationPickerElement = saturationPicker && (saturationPicker.$el as HTMLElement);
const saturationPickerElement = saturationPicker?.$el as HTMLElement | undefined;
const huePicker = this.$refs.huePicker as typeof LayoutCol;
const huePickerElement = huePicker && (huePicker.$el as HTMLElement);
const huePickerElement = huePicker?.$el as HTMLElement | undefined;
const opacityPicker = this.$refs.opacityPicker as typeof LayoutCol;
const opacityPickerElement = opacityPicker && (opacityPicker.$el as HTMLElement);
const opacityPickerElement = opacityPicker?.$el as HTMLElement | undefined;
if (!(e.currentTarget instanceof HTMLElement) || !saturationPickerElement || !huePickerElement || !opacityPickerElement) return;
@@ -216,13 +216,13 @@ export default defineComponent({
},
updateRects() {
const saturationPicker = this.$refs.saturationPicker as typeof LayoutCol;
const saturationPickerElement = saturationPicker && (saturationPicker.$el as HTMLElement);
const saturationPickerElement = saturationPicker?.$el as HTMLElement | undefined;
const huePicker = this.$refs.huePicker as typeof LayoutCol;
const huePickerElement = huePicker && (huePicker.$el as HTMLElement);
const huePickerElement = huePicker?.$el as HTMLElement | undefined;
const opacityPicker = this.$refs.opacityPicker as typeof LayoutCol;
const opacityPickerElement = opacityPicker && (opacityPicker.$el as HTMLElement);
const opacityPickerElement = opacityPicker?.$el as HTMLElement | undefined;
if (!saturationPickerElement || !huePickerElement || !opacityPickerElement) return;
@@ -9,7 +9,7 @@
<TextLabel :bold="true" class="heading">{{ dialog.state.heading }}</TextLabel>
<TextLabel class="details">{{ dialog.state.details }}</TextLabel>
<LayoutRow class="buttons-row" v-if="dialog.state.buttons.length > 0">
<TextButton v-for="(button, index) in dialog.state.buttons" :key="index" :title="button.tooltip" :action="() => button.callback && button.callback()" v-bind="button.props" />
<TextButton v-for="(button, index) in dialog.state.buttons" :key="index" :title="button.tooltip" :action="() => button.callback?.()" v-bind="button.props" />
</LayoutRow>
</LayoutCol>
</LayoutRow>
@@ -212,7 +212,7 @@ export default defineComponent({
const workspace = document.querySelector("[data-workspace]");
const floatingMenuContainer = this.$refs.floatingMenuContainer as HTMLElement;
const floatingMenuContentComponent = this.$refs.floatingMenuContent as typeof LayoutCol;
const floatingMenuContent = floatingMenuContentComponent && (floatingMenuContentComponent.$el as HTMLElement);
const floatingMenuContent: HTMLElement | undefined = floatingMenuContentComponent?.$el;
const floatingMenu = this.$refs.floatingMenu as HTMLElement;
if (!workspace || !floatingMenuContainer || !floatingMenuContentComponent || !floatingMenuContent || !floatingMenu) return;
@@ -298,30 +298,28 @@ export default defineComponent({
},
getWidth(callback: (width: number) => void) {
this.$nextTick(() => {
const floatingMenuContent = (this.$refs.floatingMenuContent as typeof LayoutCol).$el as HTMLElement;
const floatingMenuContent: HTMLElement = (this.$refs.floatingMenuContent as typeof LayoutCol).$el;
const width = floatingMenuContent.clientWidth;
callback(width);
});
},
disableMinWidth(callback: (minWidth: string) => void) {
this.$nextTick(() => {
const floatingMenuContent = (this.$refs.floatingMenuContent as typeof LayoutCol).$el as HTMLElement;
const floatingMenuContent: HTMLElement = (this.$refs.floatingMenuContent as typeof LayoutCol).$el;
const initialMinWidth = floatingMenuContent.style.minWidth;
floatingMenuContent.style.minWidth = "0";
callback(initialMinWidth);
});
},
enableMinWidth(minWidth: string) {
const floatingMenuContent = (this.$refs.floatingMenuContent as typeof LayoutCol).$el as HTMLElement;
const floatingMenuContent: HTMLElement = (this.$refs.floatingMenuContent as typeof LayoutCol).$el;
floatingMenuContent.style.minWidth = minWidth;
},
pointerMoveHandler(e: PointerEvent) {
const target = e.target as HTMLElement;
const pointerOverFloatingMenuKeepOpen = target && (target.closest("[data-hover-menu-keep-open]") as HTMLElement);
const pointerOverFloatingMenuSpawner = target && (target.closest("[data-hover-menu-spawner]") as HTMLElement);
// TODO: Simplify the following expression when optional chaining is supported by the build system
const pointerOverOwnFloatingMenuSpawner =
pointerOverFloatingMenuSpawner && pointerOverFloatingMenuSpawner.parentElement && pointerOverFloatingMenuSpawner.parentElement.contains(this.$refs.floatingMenu as HTMLElement);
const target = e.target as HTMLElement | undefined;
const pointerOverFloatingMenuKeepOpen = target?.closest("[data-hover-menu-keep-open]") as HTMLElement | undefined;
const pointerOverFloatingMenuSpawner = target?.closest("[data-hover-menu-spawner]") as HTMLElement | undefined;
const pointerOverOwnFloatingMenuSpawner = pointerOverFloatingMenuSpawner?.parentElement?.contains(this.$refs.floatingMenu as HTMLElement);
// Swap this open floating menu with the one created by the floating menu spawner being hovered over
if (pointerOverFloatingMenuSpawner && !pointerOverOwnFloatingMenuSpawner) {
this.setClosed();
@@ -372,10 +370,12 @@ export default defineComponent({
},
isPointerEventOutsideMenuElement(e: PointerEvent, element: HTMLElement, extraDistanceAllowed = 0): boolean {
const floatingMenuBounds = element.getBoundingClientRect();
if (floatingMenuBounds.left - e.clientX >= extraDistanceAllowed) return true;
if (e.clientX - floatingMenuBounds.right >= extraDistanceAllowed) return true;
if (floatingMenuBounds.top - e.clientY >= extraDistanceAllowed) return true;
if (e.clientY - floatingMenuBounds.bottom >= extraDistanceAllowed) return true;
return false;
},
},
@@ -19,9 +19,9 @@
<span class="entry-label">{{ entry.label }}</span>
<IconLabel v-if="entry.shortcutRequiresLock && !fullscreen.state.keyboardLocked" :icon="'Info'" :title="keyboardLockInfoMessage" />
<UserInputLabel v-else-if="entry.shortcut && entry.shortcut.length" :inputKeys="[entry.shortcut]" />
<UserInputLabel v-else-if="entry.shortcut?.length" :inputKeys="[entry.shortcut]" />
<div class="submenu-arrow" v-if="entry.children && entry.children.length"></div>
<div class="submenu-arrow" v-if="entry.children?.length"></div>
<div class="no-submenu-arrow" v-else></div>
<MenuList
@@ -175,10 +175,10 @@ const MenuList = defineComponent({
scrollableY: { type: Boolean as PropType<boolean>, default: false },
},
methods: {
setEntryRefs(menuEntry: MenuListEntry, ref: typeof FloatingMenu) {
setEntryRefs(menuEntry: MenuListEntry, ref: typeof FloatingMenu): void {
if (ref) menuEntry.ref = ref;
},
handleEntryClick(menuEntry: MenuListEntry) {
handleEntryClick(menuEntry: MenuListEntry): void {
(this.$refs.floatingMenu as typeof FloatingMenu).setClosed();
if (menuEntry.checkbox) menuEntry.checked = !menuEntry.checked;
@@ -188,20 +188,20 @@ const MenuList = defineComponent({
this.$emit("update:activeEntry", menuEntry);
},
handleEntryPointerEnter(menuEntry: MenuListEntry) {
if (!menuEntry.children || !menuEntry.children.length) return;
handleEntryPointerEnter(menuEntry: MenuListEntry): void {
if (!menuEntry.children?.length) return;
if (menuEntry.ref) menuEntry.ref.setOpen();
else throw new Error("The menu bar floating menu has no associated ref");
},
handleEntryPointerLeave(menuEntry: MenuListEntry) {
if (!menuEntry.children || !menuEntry.children.length) return;
handleEntryPointerLeave(menuEntry: MenuListEntry): void {
if (!menuEntry.children?.length) return;
if (menuEntry.ref) menuEntry.ref.setClosed();
else throw new Error("The menu bar floating menu has no associated ref");
},
isMenuEntryOpen(menuEntry: MenuListEntry): boolean {
if (!menuEntry.children || !menuEntry.children.length) return false;
if (!menuEntry.children?.length) return false;
if (menuEntry.ref) return menuEntry.ref.isOpen();
@@ -215,7 +215,7 @@ const MenuList = defineComponent({
},
isOpen(): boolean {
const floatingMenu = this.$refs.floatingMenu as typeof FloatingMenu;
return Boolean(floatingMenu && floatingMenu.isOpen());
return Boolean(floatingMenu?.isOpen());
},
async measureAndReportWidth() {
// API is experimental but supported in all browsers - https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/ready
@@ -242,10 +242,8 @@ const MenuList = defineComponent({
},
computed: {
menuEntriesWithoutRefs(): MenuListEntryData[][] {
const { menuEntries } = this;
return menuEntries.map((entries) =>
return this.menuEntries.map((entries) =>
entries.map((entry) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { ref, ...entryWithoutRef } = entry;
return entryWithoutRef;
})