Skip to content

Commit

Permalink
feat: different styles for different components
Browse files Browse the repository at this point in the history
  • Loading branch information
dbajpeyi committed Sep 26, 2024
1 parent 999c3a8 commit 4bf9a8d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 60 deletions.
125 changes: 77 additions & 48 deletions build/integration/contentScope.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,25 +557,27 @@

/**
*
* @param {() => HTMLElement} fn
* @param {() => Element|HTMLElement|null} fn
* @param {number} maxAttempts
* @param {number} delay
* @returns {HTMLElement|undefined}
* @returns {Promise<Element|HTMLElement|null>}
*/
function withExponentialBackoff (fn, maxAttempts = 4, delay = 500) {
const call = (attempt) => {
const result = fn();
if (result) {
return result
} else {
if (attempt >= maxAttempts) {
throw new Error$1('Could not find element after max attempts')
return new Promise((resolve, reject) => {
let attempts = 0;
const tryFn = () => {
attempts += 1;
const element = fn();
if (element) {
resolve(element);
} else if (attempts < maxAttempts) {
setTimeout(tryFn, delay * Math.pow(2, attempts));
} else {
setTimeout(() => call(attempt + 1), delay * 2 ** attempt);
reject(new Error$1('Element not found'));
}
}
};
return call(0)
};
tryFn();
})
}

/**
Expand Down Expand Up @@ -22034,86 +22036,113 @@
}
}

const URL_ELEMENT_MAP = {
'/': {
name: 'cogWheel',
style: {
scale: 1,
backgroundColor: 'rgba(0, 39, 142, 0.5)'
}
},
'/options': {
name: 'exportButton',
style: {
scale: 1.01,
backgroundColor: 'rgba(0, 39, 142, 0.5)'
}
},
'/intro': {
name: 'signInButton',
style: {
scale: 1.5,
backgroundColor: 'rgba(0, 39, 142, 0.5)'
}
}
};

class PasswordImport extends ContentFeature {
findExportElement () {
const xpath = "//div[text()='Export passwords']/ancestor::li"; // Should be configurable
return getElement(document, xpath)
}

animateElement (element) {
animateElement (element, style) {
element.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
}); // Scroll into view
const keyframes = [
{ backgroundColor: 'transparent' },
{ backgroundColor: 'lightblue' },
{ backgroundColor: 'transparent' }
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 0 }, // Start: transparent
{ backgroundColor: style.backgroundColor, offset: 0.5, transform: `scale(${style.scale})` }, // Midpoint: blue with 50% opacity
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 1 } // End: transparent
];

// Define the animation options
const options = {
duration: 1000, // 1 second, should be configurable
iterations: Infinity
};

// Apply the animation to the element
element.animate(keyframes, options);
}

findSettingsElement () {
return document.querySelector(`[aria-label='Password options']`)
return document.querySelector('[aria-label=\'Password options\']')
}

findSignInButton () {
return document.querySelector(`[aria-label='Sign in']`)
return document.querySelector('[aria-label="Sign in"]:not([target="_top"])')
}

async findElementForPage (page) {
switch (page) {
case 'exportPasswordsPage':
return this.findExportElement()
case 'landingPage':
return this.findSettingsElement()
case 'signInPage':
return this.findSignInButton()
default:
throw new Error('Page not supported')
async findElement (name) {
let fn = null;
switch (name) {
case 'exportButton':
fn = this.findExportElement;
break
case 'cogWheel':
fn = this.findSettingsElement;
break
case 'signInButton':
fn = this.findSignInButton;
break
default:
throw new Error('Page not supported')
}
return await withExponentialBackoff(fn)
}

init () {
const animateElement = this.animateElement.bind(this);
const findExportElement = this.findExportElement.bind(this);
const findElement = this.findElement.bind(this);
// FIXME: this is stolen from element-hiding.js, we would need a global util that would do this,
// single page applications don't have a DOMContentLoaded event on navigations, so
// we use proxy/reflect on history.pushState to find elements on page navigations
const historyMethodProxy = new DDGProxy(this, History.prototype, 'pushState', {
apply (target, thisArg, args) {
console.log("pushState URL", window.location.pathname);
const element = withExponentialBackoff(() => {
return findExportElement()
});
animateElement(element);
async apply (target, thisArg, args) {
const pageURL = args[2].split('?')[0];
const { name, style } = URL_ELEMENT_MAP[pageURL];
const element = await findElement(name);
animateElement(element, style);
return DDGReflect.apply(target, thisArg, args)
}
});
historyMethodProxy.overload();
// listen for popstate events in order to run on back/forward navigations
window.addEventListener('popstate', () => {
console.log("pushState URL", window.location.pathname);
const element = withExponentialBackoff(() => {
return findExportElement()
});
animateElement(element);
window.addEventListener('popstate', async () => {
console.log('pushState URL', window.location.pathname);
const { name, style } = URL_ELEMENT_MAP[window.location.pathname];
const element = await findElement(name);
animateElement(element, style);
});

document.addEventListener('DOMContentLoaded', () => {
console.log("pushState URL", window.location.pathname);
const element = withExponentialBackoff(() => {
return findExportElement()
});
animateElement(element);
document.addEventListener('DOMContentLoaded', async () => {
console.log('pushState URL', window.location.pathname);
const { name, style } = URL_ELEMENT_MAP[window.location.pathname];
const element = await findElement(name);
animateElement(element, style);
});
}
}
Expand Down
23 changes: 11 additions & 12 deletions src/features/password-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import ContentFeature from '../content-feature'
import { DDGProxy, DDGReflect, withExponentialBackoff } from '../utils'
import { getElement } from './broker-protection/utils'


const URL_ELEMENT_MAP = {
'/': {
name: 'cogWheel',
Expand All @@ -12,18 +11,18 @@ const URL_ELEMENT_MAP = {
}
},
'/options': {
name: 'exportButton',
name: 'exportButton',
style: {
scale: 1.01,
backgroundColor: 'rgba(0, 39, 142, 0.5)'
}
},
'/intro': {
name: 'signInButton',
name: 'signInButton',
style: {
scale: 1.5,
backgroundColor: 'rgba(0, 39, 142, 0.3)'
},
backgroundColor: 'rgba(0, 39, 142, 0.5)'
}
}
}

Expand All @@ -40,9 +39,9 @@ export default class PasswordImport extends ContentFeature {
inline: 'center'
}) // Scroll into view
const keyframes = [
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 0 }, // Start: transparent
{ backgroundColor: style.backgroundColor, offset: 0.5, transform: `scale(${style.scale})` }, // Midpoint: blue with 50% opacity
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 1 } // End: transparent
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 0 }, // Start: transparent
{ backgroundColor: style.backgroundColor, offset: 0.5, transform: `scale(${style.scale})` }, // Midpoint: blue with 50% opacity
{ backgroundColor: 'rgba(0, 0, 255, 0)', offset: 1 } // End: transparent
]

// Define the animation options
Expand All @@ -60,7 +59,7 @@ export default class PasswordImport extends ContentFeature {
}

findSignInButton () {
return document.querySelector('[aria-label="Sign in"]:not([target="_top"])');
return document.querySelector('[aria-label="Sign in"]:not([target="_top"])')
}

async findElement (name) {
Expand Down Expand Up @@ -90,7 +89,7 @@ export default class PasswordImport extends ContentFeature {
const historyMethodProxy = new DDGProxy(this, History.prototype, 'pushState', {
async apply (target, thisArg, args) {
const pageURL = args[2].split('?')[0]
const {name, style} = URL_ELEMENT_MAP[pageURL]
const { name, style } = URL_ELEMENT_MAP[pageURL]
const element = await findElement(name)
animateElement(element, style)
return DDGReflect.apply(target, thisArg, args)
Expand All @@ -100,14 +99,14 @@ export default class PasswordImport extends ContentFeature {
// listen for popstate events in order to run on back/forward navigations
window.addEventListener('popstate', async () => {
console.log('pushState URL', window.location.pathname)
const {name, style} = URL_ELEMENT_MAP[window.location.pathname]
const { name, style } = URL_ELEMENT_MAP[window.location.pathname]
const element = await findElement(name)
animateElement(element, style)
})

document.addEventListener('DOMContentLoaded', async () => {
console.log('pushState URL', window.location.pathname)
const {name, style} = URL_ELEMENT_MAP[window.location.pathname]
const { name, style } = URL_ELEMENT_MAP[window.location.pathname]
const element = await findElement(name)
animateElement(element, style)
})
Expand Down

0 comments on commit 4bf9a8d

Please sign in to comment.