fix: update client app navigation

Closes #360.
pull/376/head
dessant 2 years ago
parent 4c7dd3ea2a
commit 3fae62ee4a

@ -546,10 +546,51 @@ async function onMessage(request, sender) {
await resetCaptcha(sender.tab.id, sender.frameId, request.challengeUrl);
} else if (request.id === 'getFramePos') {
return getFramePos(sender.tab.id, sender.frameId, request.frameIndex);
} else if (request.id === 'getTabZoom') {
return browser.tabs.getZoom(sender.tab.id);
} else if (request.id === 'getBackgroundScriptScale') {
return window.devicePixelRatio;
} else if (request.id === 'getOsScale') {
let zoom = await browser.tabs.getZoom(sender.tab.id);
const [[scale, windowWidth]] = await browser.tabs.executeScript(
sender.tab.id,
{
code: `[window.devicePixelRatio, window.innerWidth];`,
runAt: 'document_start'
}
);
if (targetEnv === 'firefox') {
// https://bugzilla.mozilla.org/show_bug.cgi?id=1787649
function getImageElement(url) {
return new Promise(resolve => {
const img = new Image();
img.onload = () => {
resolve(img);
};
img.onerror = () => {
resolve();
};
img.onabort = () => {
resolve();
};
img.src = url;
});
}
const screenshotWidth = (
await getImageElement(
await browser.tabs.captureVisibleTab({
format: 'jpeg',
quality: 10
})
)
).naturalWidth;
if (Math.abs(screenshotWidth / windowWidth - scale * zoom) < 0.005) {
zoom = 1;
}
}
return scale / zoom;
} else if (request.id === 'startClientApp') {
nativePort = browser.runtime.connectNative('org.buster.client');
} else if (request.id === 'stopClientApp') {

@ -6,7 +6,7 @@ function initReset(challengeUrl) {
new CustomEvent('___resetCaptcha', {detail: challengeUrl})
);
};
script.src = chrome.extension.getURL('/src/content/reset.js');
script.src = chrome.runtime.getURL('/src/content/reset.js');
document.documentElement.appendChild(script);
}

@ -1,5 +1,5 @@
function setup() {
const url = new URL(chrome.extension.getURL('/src/setup/index.html'));
const url = new URL(chrome.runtime.getURL('/src/setup/index.html'));
url.searchParams.set(
'session',
new URL(window.location.href).searchParams.get('session')

@ -2,7 +2,13 @@ import browser from 'webextension-polyfill';
import storage from 'storage/storage';
import {meanSleep, pingClientApp} from 'utils/app';
import {getText, waitForElement, getRandomFloat, sleep} from 'utils/common';
import {
getText,
waitForElement,
getRandomFloat,
sleep,
getBrowser
} from 'utils/common';
import {targetEnv, clientAppVersion} from 'utils/config';
let solverWorking = false;
@ -51,13 +57,18 @@ function syncUI() {
helpButton.remove();
const helpButtonHolder = document.querySelector('.help-button-holder');
const shadow = helpButtonHolder.attachShadow({mode: 'closed'});
helpButtonHolder.tabIndex = 2;
const shadow = helpButtonHolder.attachShadow({
mode: 'closed',
delegatesFocus: true
});
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute(
'href',
browser.extension.getURL('/src/solve/solver-button.css')
browser.runtime.getURL('/src/solve/solver-button.css')
);
shadow.appendChild(link);
@ -133,8 +144,8 @@ async function tapEnter(node, {navigateForward = true} = {}) {
await messageClientApp({command: 'tapKey', data: 'enter'});
}
async function clickElement(node, browserBorder) {
const targetPos = await getClickPos(node, browserBorder);
async function clickElement(node, browserBorder, osScale) {
const targetPos = await getClickPos(node, browserBorder, osScale);
await messageClientApp({command: 'moveMouse', ...targetPos});
await meanSleep(100);
await messageClientApp({command: 'clickMouse'});
@ -154,31 +165,31 @@ async function messageClientApp(message) {
}
async function getOsScale() {
// The background script devicePixelRatio is not affected by the default
// zoom level in Firefox, while the content script devicePixelRatio
// is affected, unless only text is zoomed.
if (targetEnv === 'firefox') {
return browser.runtime.sendMessage({id: 'getBackgroundScriptScale'});
}
const zoom = await browser.runtime.sendMessage({id: 'getTabZoom'});
return window.devicePixelRatio / zoom;
return browser.runtime.sendMessage({id: 'getOsScale'});
}
async function getBrowserBorder(clickEvent) {
async function getBrowserBorder(clickEvent, osScale) {
const framePos = await getFrameClientPos();
const scale = window.devicePixelRatio;
const osScale = await getOsScale();
let evScreenPropScale = osScale;
if (
targetEnv === 'firefox' &&
parseInt((await getBrowser()).version.split('.')[0], 10) >= 99
) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=1753836
evScreenPropScale = scale;
}
return {
left:
clickEvent.screenX * osScale -
clickEvent.screenX * evScreenPropScale -
clickEvent.clientX * scale -
framePos.x -
window.screenX * scale,
top:
clickEvent.screenY * osScale -
clickEvent.screenY * evScreenPropScale -
clickEvent.clientY * scale -
framePos.y -
window.screenY * scale
@ -202,7 +213,7 @@ async function getFrameClientPos() {
return {x: 0, y: 0};
}
async function getElementScreenRect(node, browserBorder) {
async function getElementScreenRect(node, browserBorder, osScale) {
let {left: x, top: y, width, height} = node.getBoundingClientRect();
const data = await getFrameClientPos();
@ -218,7 +229,6 @@ async function getElementScreenRect(node, browserBorder) {
const {os} = await browser.runtime.sendMessage({id: 'getPlatform'});
if (['windows', 'macos'].includes(os)) {
const osScale = await getOsScale();
x /= osScale;
y /= osScale;
width /= osScale;
@ -228,8 +238,12 @@ async function getElementScreenRect(node, browserBorder) {
return {x, y, width, height};
}
async function getClickPos(node, browserBorder) {
let {x, y, width, height} = await getElementScreenRect(node, browserBorder);
async function getClickPos(node, browserBorder, osScale) {
let {x, y, width, height} = await getElementScreenRect(
node,
browserBorder,
osScale
);
return {
x: Math.round(x + width * getRandomFloat(0.4, 0.6)),
@ -248,10 +262,12 @@ async function solve(simulateUserInput, clickEvent) {
);
let browserBorder;
let osScale;
let useMouse = true;
if (simulateUserInput) {
if (!navigateWithKeyboard && (clickEvent.clientX || clickEvent.clientY)) {
browserBorder = await getBrowserBorder(clickEvent);
osScale = await getOsScale();
browserBorder = await getBrowserBorder(clickEvent, osScale);
} else {
useMouse = false;
}
@ -263,9 +279,10 @@ async function solve(simulateUserInput, clickEvent) {
const audioButton = document.querySelector('#recaptcha-audio-button');
if (simulateUserInput) {
if (useMouse) {
await clickElement(audioButton, browserBorder);
await clickElement(audioButton, browserBorder, osScale);
} else {
await tapEnter(audioButton, {navigateForward: false});
audioButton.focus();
await tapEnter(audioButton);
}
} else {
dispatchEnter(audioButton);
@ -325,7 +342,7 @@ async function solve(simulateUserInput, clickEvent) {
'.rc-audiochallenge-play-button > button'
);
if (useMouse) {
await clickElement(playButton, browserBorder);
await clickElement(playButton, browserBorder, osScale);
} else {
await tapEnter(playButton);
}
@ -347,7 +364,7 @@ async function solve(simulateUserInput, clickEvent) {
const input = document.querySelector('#audio-response');
if (simulateUserInput) {
if (useMouse) {
await clickElement(input, browserBorder);
await clickElement(input, browserBorder, osScale);
} else {
await navigateToElement(input);
}
@ -361,7 +378,7 @@ async function solve(simulateUserInput, clickEvent) {
const submitButton = document.querySelector('#recaptcha-verify-button');
if (simulateUserInput) {
if (useMouse) {
await clickElement(submitButton, browserBorder);
await clickElement(submitButton, browserBorder, osScale);
} else {
await tapEnter(submitButton);
}

@ -21,6 +21,10 @@
outline: none;
}
#solver-button:focus-visible {
background-color: rgba(216, 216, 216, 0.8);
}
#solver-button.working {
background-image: url('data:image/svg+xml,%3Csvg%20width%3D%2244%22%20height%3D%2244%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20stroke%3D%22%23727272%22%3E%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%20stroke-width%3D%225%22%3E%3Ccircle%20cx%3D%2222%22%20cy%3D%2222%22%20r%3D%221%22%3E%3Canimate%20attributeName%3D%22r%22%20begin%3D%220s%22%20dur%3D%221.8s%22%20values%3D%221%3B%2020%22%20calcMode%3D%22spline%22%20keyTimes%3D%220%3B%201%22%20keySplines%3D%220.165%2C%200.84%2C%200.44%2C%201%22%20repeatCount%3D%22indefinite%22%2F%3E%3Canimate%20attributeName%3D%22stroke-opacity%22%20begin%3D%220s%22%20dur%3D%221.8s%22%20values%3D%221%3B%200%22%20calcMode%3D%22spline%22%20keyTimes%3D%220%3B%201%22%20keySplines%3D%220.3%2C%200.61%2C%200.355%2C%201%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Ccircle%20cx%3D%2222%22%20cy%3D%2222%22%20r%3D%221%22%3E%3Canimate%20attributeName%3D%22r%22%20begin%3D%22-0.9s%22%20dur%3D%221.8s%22%20values%3D%221%3B%2020%22%20calcMode%3D%22spline%22%20keyTimes%3D%220%3B%201%22%20keySplines%3D%220.165%2C%200.84%2C%200.44%2C%201%22%20repeatCount%3D%22indefinite%22%2F%3E%3Canimate%20attributeName%3D%22stroke-opacity%22%20begin%3D%22-0.9s%22%20dur%3D%221.8s%22%20values%3D%221%3B%200%22%20calcMode%3D%22spline%22%20keyTimes%3D%220%3B%201%22%20keySplines%3D%220.3%2C%200.61%2C%200.355%2C%201%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E') !important;
opacity: 1;

@ -57,7 +57,7 @@ function getOptionLabels(data, scope = 'optionValue') {
async function showContributePage(action = false) {
const activeTab = await getActiveTab();
let url = browser.extension.getURL('/src/contribute/index.html');
let url = browser.runtime.getURL('/src/contribute/index.html');
if (action) {
url = `${url}?action=${action}`;
}

Loading…
Cancel
Save