Skip to content

Commit

Permalink
feat: refactor for scroll
Browse files Browse the repository at this point in the history
  • Loading branch information
dbajpeyi committed Nov 5, 2024
1 parent 7d4a3af commit 99a99cb
Showing 1 changed file with 45 additions and 10 deletions.
55 changes: 45 additions & 10 deletions injected/src/features/autofill-password-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class AutofillPasswordImport extends ContentFeature {
#exportButtonSettings
#settingsButtonSettings
#signInButtonSettings
#elementToCenterOn

/**
* @returns {any}
Expand Down Expand Up @@ -117,9 +118,34 @@ export default class AutofillPasswordImport extends ContentFeature {
if (existingOverlay != null) {
existingOverlay.style.display = 'none'
existingOverlay.remove()
document.removeEventListener('scroll', this.updateOverlayPosition.bind(this))
}
}

/**
* Updates the position of the overlay based on the element to center on.
* @param {HTMLDivElement} overlay
* @param {any} style
*/
updateOverlayPosition (overlay, style) {
const animations = overlay.getAnimations()
animations.forEach(animation => animation.pause())
const { top, left, width, height } = this.elementToCenterOn.getBoundingClientRect()
overlay.style.position = 'absolute'

const isRound = style.borderRadius === '100%'

const widthOffset = isRound ? (width/2) : 0
const heightOffset = isRound ? (height/2) : 0

overlay.style.top = `calc(${top}px + ${window.scrollY}px - ${widthOffset}px - 1px - ${style.offsetTopEm}em)`
overlay.style.left = `calc(${left}px + ${window.scrollX}px - ${heightOffset}px - 1px - ${style.offsetLeftEm}em)`

// Ensure overlay is non-interactive
overlay.style.pointerEvents = 'none'
animations.forEach(animation => animation.play())
}

/**
* Inserts an overlay element to animate, by adding a div to the body
* and styling it based on the found element.
Expand All @@ -130,26 +156,25 @@ export default class AutofillPasswordImport extends ContentFeature {
insertOverlayElement (mainElement, style) {
this.removeOverlayIfNeeded()


const overlay = document.createElement('div')
overlay.setAttribute('id', OVERLAY_ID)
const svgElement = mainElement.parentNode?.querySelector('svg') ?? mainElement.querySelector('svg')

const isRound = style.borderRadius === '100%'
const elementToCenterOn = (isRound && svgElement != null) ? svgElement : mainElement
if (elementToCenterOn) {
const { top, left, width, height } = elementToCenterOn.getBoundingClientRect()
overlay.style.position = 'absolute'

overlay.style.top = `calc(${top}px + ${window.scrollY}px - ${isRound ? height / 2 : 0}px - 1px - ${style.offsetTopEm}em)`
overlay.style.left = `calc(${left}px + ${window.scrollX}px - ${isRound ? width / 2 : 0}px - 1px - ${style.offsetLeftEm}em)`

if (this.elementToCenterOn != null) {

this.updateOverlayPosition(overlay, style)

const mainElementRect = mainElement.getBoundingClientRect()
overlay.style.width = `${mainElementRect.width}px`
overlay.style.height = `${mainElementRect.height}px`
overlay.style.zIndex = style.zIndex

// Ensure overlay is non-interactive
overlay.style.pointerEvents = 'none'

document.addEventListener('scroll', () => {
requestAnimationFrame(() => this.updateOverlayPosition(overlay, style))
})

// insert in document.body
document.body.appendChild(overlay)
Expand Down Expand Up @@ -182,6 +207,15 @@ export default class AutofillPasswordImport extends ContentFeature {
observer.observe(document.body, { childList: true, subtree: true })
}

setElementToCenterOn (element, style) {
const svgElement = element.parentNode?.querySelector('svg') ?? element.querySelector('svg')
this.#elementToCenterOn = (style.borderRadius === '100%' && svgElement != null) ? svgElement : element
}

get elementToCenterOn () {
return this.#elementToCenterOn
}

/**
* Moves the element into view and animates it.
* @param {HTMLElement|Element} element
Expand Down Expand Up @@ -267,6 +301,7 @@ export default class AutofillPasswordImport extends ContentFeature {
if (supportedPaths.includes(path)) {
try {
const { element, style, shouldTap, shouldWatchForRemoval } = await this.getElementAndStyleFromPath(path) ?? {}
this.setElementToCenterOn(element, style)
if (element != null) {
if (shouldTap) {
this.autotapElement(element)
Expand Down

0 comments on commit 99a99cb

Please sign in to comment.