bits-ui
Version:
The headless components for Svelte.
91 lines (90 loc) • 3.82 kB
JavaScript
import { getWindow } from "svelte-toolbelt";
const PWM_BADGE_MARGIN_RIGHT = 18;
const PWM_BADGE_SPACE_WIDTH_PX = 40;
const PWM_BADGE_SPACE_WIDTH = `${PWM_BADGE_SPACE_WIDTH_PX}px`;
const PASSWORD_MANAGER_SELECTORS = [
"[data-lastpass-icon-root]", // LastPass,
"com-1password-button", // 1Password,
"[data-dashlanecreated]", // Dashlane,
'[style$="2147483647 !important;"]', // Bitwarden
].join(",");
export function usePasswordManagerBadge({ containerRef, inputRef, pushPasswordManagerStrategy, isFocused, domContext, }) {
let hasPwmBadge = $state(false);
let hasPwmBadgeSpace = $state(false);
let done = $state(false);
function willPushPwmBadge() {
const strategy = pushPasswordManagerStrategy.current;
if (strategy === "none")
return false;
const increaseWidthCase = strategy === "increase-width" && hasPwmBadge && hasPwmBadgeSpace;
return increaseWidthCase;
}
function trackPwmBadge() {
const container = containerRef.current;
const input = inputRef.current;
if (!container || !input || done || pushPasswordManagerStrategy.current === "none")
return;
const elementToCompare = container;
// get the top right-center point of the container
// that is usually where most password managers place their badge
const rightCornerX = elementToCompare.getBoundingClientRect().left + elementToCompare.offsetWidth;
const centeredY = elementToCompare.getBoundingClientRect().top + elementToCompare.offsetHeight / 2;
const x = rightCornerX - PWM_BADGE_MARGIN_RIGHT;
const y = centeredY;
// do an extra search to check for all the password manager badges
const passwordManagerStrategy = domContext.querySelectorAll(PASSWORD_MANAGER_SELECTORS);
// if no password manager is detected, dispatch document.elementFromPoint to
// identify the badges
if (passwordManagerStrategy.length === 0) {
const maybeBadgeEl = domContext.getDocument().elementFromPoint(x, y);
// if the found element is the container,
// then it is not a badge, most times there is no badge in this case
if (maybeBadgeEl === container)
return;
}
hasPwmBadge = true;
done = true;
}
$effect(() => {
const container = containerRef.current;
if (!container || pushPasswordManagerStrategy.current === "none")
return;
// check if the pwm area is fully visible
function checkHasSpace() {
const viewportWidth = getWindow(container).innerWidth;
const distanceToRightEdge = viewportWidth - container.getBoundingClientRect().right;
hasPwmBadgeSpace = distanceToRightEdge >= PWM_BADGE_SPACE_WIDTH_PX;
}
checkHasSpace();
const interval = setInterval(checkHasSpace, 1000);
return () => {
clearInterval(interval);
};
});
$effect(() => {
const focused = isFocused.current || domContext.getActiveElement() === inputRef.current;
if (pushPasswordManagerStrategy.current === "none" || !focused)
return;
const t1 = setTimeout(trackPwmBadge, 0);
const t2 = setTimeout(trackPwmBadge, 2000);
const t3 = setTimeout(trackPwmBadge, 5000);
const t4 = setTimeout(() => {
done = true;
}, 6000);
return () => {
clearTimeout(t1);
clearTimeout(t2);
clearTimeout(t3);
clearTimeout(t4);
};
});
return {
get hasPwmBadge() {
return hasPwmBadge;
},
get willPushPwmBadge() {
return willPushPwmBadge();
},
PWM_BADGE_SPACE_WIDTH,
};
}