Skip to content

Commit

Permalink
turn menu into a module
Browse files Browse the repository at this point in the history
  • Loading branch information
GooseOb committed Jan 6, 2025
1 parent 5754d0c commit 7360107
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 75 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "yt-defaulter",
"author": "GooseOb",
"version": "1.11.15",
"version": "1.11.16",
"repository": {
"type": "git",
"url": "git+https://github.com/GooseOb/YT-Defaulter.git"
Expand Down
6 changes: 3 additions & 3 deletions src/listeners/video-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ export const onVideoPage = async () => {

applySettings(computeSettings(doNotChangeSpeed));

if (!menu.value.element) {
if (!menu.element) {
menu.init();
}
});

if (menu.value.element) {
menu.updateThisChannel(config.channel.get());
if (menu.element) {
menu.updateThisChannel();
}
};
29 changes: 29 additions & 0 deletions src/menu/close.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { isDescendantOrTheSame } from '../utils';
import { element, btn } from './value';

export const close = () => {
element.style.visibility = 'hidden';
stopListening();
};

export const listenForClose = () => {
document.addEventListener('click', onClick);
document.addEventListener('keyup', onKeyUp);
};

const stopListening = () => {
document.removeEventListener('click', onClick);
document.removeEventListener('keyup', onKeyUp);
};

const onClick = (e: Event) => {
const el = e.target as HTMLElement;
if (!isDescendantOrTheSame(el, [element, btn])) close();
};

const onKeyUp = (e: KeyboardEvent) => {
if (e.code === 'Escape') {
close();
btn.focus();
}
};
43 changes: 22 additions & 21 deletions src/menu/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { section } from './section';
import { settingsIcon } from './settings-icon';
import * as config from '../config';
import { withOnClick } from '../utils/with';
import { value } from './value';
import * as menu from './value';
import { untilAppear } from '../utils';
import * as get from '../element-getters';

Expand Down Expand Up @@ -72,24 +72,25 @@ export const init = () => {
})
);

value.btn = withOnClick(
button('', {
id: BTN_ID,
ariaLabel: text.OPEN_SETTINGS,
tabIndex: 0,
menu.set(
div({
id: MENU_ID,
}),
() => {
value.toggle();
}
withOnClick(
button('', {
id: BTN_ID,
ariaLabel: text.OPEN_SETTINGS,
tabIndex: 0,
}),
menu.toggle
)
);
value.btn.setAttribute('aria-controls', MENU_ID);
value.btn.classList.add(btnClass + '--icon-button');
value.btn.append(settingsIcon());

value.element = div({
id: MENU_ID,
});
value.element.append(
menu.btn.setAttribute('aria-controls', MENU_ID);
menu.btn.classList.add(btnClass + '--icon-button');
menu.btn.append(settingsIcon());

menu.element.append(
sections,
controlCheckboxDiv('shorts', 'shortsToUsual', text.SHORTS),
controlCheckboxDiv('new-tab', 'newTab', text.NEW_TAB),
Expand All @@ -107,20 +108,20 @@ export const init = () => {
controlDiv,
controlStatus
);
value.element.addEventListener('keyup', (e) => {
menu.element.addEventListener('keyup', (e) => {
const el = e.target as HTMLInputElement;
if (e.code === 'Enter' && el.type === 'checkbox') el.checked = !el.checked;
});

untilAppear(get.actionsBar).then((actionsBar) => {
actionsBar.insertBefore(value.btn, actionsBar.lastChild);
get.popupContainer().append(value.element);
value.width = value.element.getBoundingClientRect().width;
actionsBar.insertBefore(menu.btn, actionsBar.lastChild);
get.popupContainer().append(menu.element);
menu.adjustWidth();
sections.style.maxWidth = sections.offsetWidth + 'px';
});

const listener = () => {
if (value.isOpen) value.fixPosition();
if (menu.isOpen) menu.fixPosition();
};
window.addEventListener('scroll', listener);
window.addEventListener('resize', listener);
Expand Down
4 changes: 2 additions & 2 deletions src/menu/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { withControlListeners, withHint } from '../utils/with';
import { getControlCreators } from './get-controls-creators';
import { validateVolume } from './validate-volume';
import { Hint } from '../hint';
import { value } from './value';
import { setFirstFocusable } from './value';
import { getElCreator } from '../utils';
import { speedNormal } from '../player';
import * as controls from './controls';
Expand Down Expand Up @@ -52,7 +52,7 @@ export const section = (
values: ['2', '1.75', '1.5', '1.25', speedNormal, '0.75', '0.5', '0.25'],
getText: (val) => val,
});
if (sectionId === SECTION_GLOBAL) value.firstFocusable = speedSelect.elem;
if (sectionId === SECTION_GLOBAL) setFirstFocusable(speedSelect.elem);

const sectionElement = div({ role: 'group' });
sectionElement.setAttribute('aria-labelledby', sectionId);
Expand Down
85 changes: 37 additions & 48 deletions src/menu/value.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,41 @@
import { debounce, isDescendantOrTheSame } from '../utils';
import { debounce } from '../utils';
import { close, listenForClose } from './close';

export const set = (el: HTMLDivElement, btnEl: HTMLButtonElement) => {
element = el;
btn = btnEl;
};

export let element = null as HTMLDivElement;
export let btn = null as HTMLButtonElement;
export let isOpen = false;

let menuWidth = 0;
export const adjustWidth = () => {
menuWidth = element.getBoundingClientRect().width;
};

type Focusable = { focus(): void };
let firstFocusable = null as Focusable;
export const setFirstFocusable = (el: Focusable) => {
firstFocusable = el;
};

export const toggle = debounce(() => {
isOpen = !isOpen;
if (isOpen) {
fixPosition();
element.style.visibility = 'visible';
listenForClose();
firstFocusable.focus();
} else {
close();
}
}, 100);

export const value = {
element: null as HTMLDivElement,
btn: null as HTMLButtonElement,
isOpen: false,
width: 0,
_closeListener: {
onClick(e: Event) {
const el = e.target as HTMLElement;
if (!isDescendantOrTheSame(el, [value.element, value.btn]))
value.toggle();
},
onKeyUp(e: KeyboardEvent) {
if (e.code === 'Escape') {
value._setOpen(false);
value.btn.focus();
}
},
add() {
document.addEventListener('click', this.onClick);
document.addEventListener('keyup', this.onKeyUp);
},
remove() {
document.removeEventListener('click', this.onClick);
document.removeEventListener('keyup', this.onKeyUp);
},
},
firstFocusable: null as Focusable,
_setOpen(bool: boolean) {
if (bool) {
this.fixPosition();
this.element.style.visibility = 'visible';
this._closeListener.add();
this.firstFocusable.focus();
} else {
this.element.style.visibility = 'hidden';
this._closeListener.remove();
}
this.isOpen = bool;
},
toggle: debounce(function () {
this._setOpen(!this.isOpen);
}, 100),
fixPosition() {
const { y, height, width, left } = this.btn.getBoundingClientRect();
this.element.style.top = y + height + 8 + 'px';
this.element.style.left = left + width - this.width + 'px';
},
export const fixPosition = () => {
const { y, height, width, left } = btn.getBoundingClientRect();
element.style.top = y + height + 8 + 'px';
element.style.left = left + width - menuWidth + 'px';
console.log(element.style.left);
};

0 comments on commit 7360107

Please sign in to comment.