bc100-autofill/content_script.js

219 lines
7.8 KiB
JavaScript
Raw Normal View History

2023-10-14 16:28:19 +02:00
"use strict";
2023-10-13 20:48:11 +02:00
// Put all the javascript code here, that you want to execute after page load.
2023-10-14 16:28:19 +02:00
let currentStage;
2023-10-13 20:48:11 +02:00
2023-10-14 16:28:19 +02:00
function executeStage(node) {
if (node.nodeType === 1) {
if (currentStage === undefined) {
currentStage = stages.shift();
}
if (currentStage.match(node)) {
console.log(currentStage.name, "matched");
console.log(currentStage.name, currentStage.execute(node) ? "executed" : "execution failed");
if (stages.length > 0) {
currentStage = stages.shift();
} else {
observer.disconnect();
}
} else {
2023-11-13 20:32:57 +01:00
console.log(currentStage.name, "did not match: ", node);
2023-10-14 16:28:19 +02:00
}
2023-10-13 20:48:11 +02:00
}
}
2023-11-13 20:32:57 +01:00
let stages;
const personalDataConfigKeys = ["addr__appellation", "addr__firstName", "addr__surName", "addr__email", "addr__street", "addr__postcode", "addr__placename"];
const bankDetailConfigKeys = ["pymt__iban", "pymt__bic"];
2023-10-13 20:48:11 +02:00
function processMutations(mutationList, observer) {
for (const mutation of mutationList) {
if (mutation.type === "childList") {
2023-10-14 16:28:19 +02:00
mutation.addedNodes.forEach(executeStage);
2023-10-13 20:48:11 +02:00
}
}
}
2023-10-14 16:28:19 +02:00
let clickThroughForms;
2023-11-13 22:42:42 +01:00
let hasConfiguredBankDetails, hasConfiguredPersonalData;
2023-10-13 20:48:11 +02:00
let observer = new MutationObserver(processMutations);
const addObserver = () => {
2023-11-13 22:42:42 +01:00
browser.storage.sync.get(['autocontinue', 'enable'].concat(personalDataConfigKeys, bankDetailConfigKeys)).then(v => {
2023-10-13 20:48:11 +02:00
clickThroughForms = !!v.autocontinue;
2023-11-13 22:42:42 +01:00
hasConfiguredPersonalData = Object.keys(v).filter(k => personalDataConfigKeys.includes(k)).length > 0;
hasConfiguredBankDetails = Object.keys(v).filter(k => bankDetailConfigKeys.includes(k)).length > 0;
2023-10-17 18:56:19 +02:00
if (!!v.enable) {
observer.observe(document.body, {
childList: true, subtree: true
})
}
2023-10-13 20:48:11 +02:00
})
};
addObserver();
2023-11-13 20:32:57 +01:00
function fillTextInput(parentNode, selector, value) {
const node = parentNode.querySelector(selector);
2023-11-13 22:42:42 +01:00
node.value = value;
node.dispatchEvent(new Event("input", { bubbles: true }));
2023-11-13 20:32:57 +01:00
}
2023-10-14 16:28:19 +02:00
const startClaim = {
name: "startClaim",
match: node => node.classList.contains("antrag-starten"),
execute: node => {
const startenButton = node.querySelector('button.test-antrag-starten-button');
if (startenButton instanceof HTMLButtonElement) {
startenButton.dispatchEvent(new Event('click', { bubbles: true }));
return true;
}
return false;
}
}
function fillBcnum(bcNumberInput) {
2023-10-13 20:48:11 +02:00
browser.storage.sync.get('bcnum').then(v => {
let bcNum = v.bcnum || null;
if (bcNum !== null && bcNum !== "") {
bcNumberInput.value = bcNum;
bcNumberInput.dispatchEvent(new Event('input', { bubbles: true }));
2023-10-14 16:28:19 +02:00
return true;
2023-10-13 20:48:11 +02:00
}
})
2023-10-14 16:28:19 +02:00
return false;
2023-10-13 20:48:11 +02:00
}
2023-10-14 16:28:19 +02:00
function fillBday(birthdayInput) {
2023-10-13 20:48:11 +02:00
browser.storage.sync.get('bday').then(v => {
2023-10-14 16:28:19 +02:00
const bDay = v.bday || null;
2023-10-13 20:48:11 +02:00
if (bDay !== null && bDay !== "") {
birthdayInput.value = bDay;
birthdayInput.dispatchEvent(new Event('input', { bubbles: true }));
2023-10-14 16:28:19 +02:00
return true;
2023-10-13 20:48:11 +02:00
}
})
2023-10-14 16:28:19 +02:00
return false;
}
const fillData = {
name: "fillData",
match: node => node.classList.contains("fahrgastrechte-bahn-card-auswahl"),
execute: node => {
let bcNumField, bdayField;
node.querySelectorAll('input').forEach(e => {
if (e.name === "fahrgastrechte-bahn-card-nummer") {
bcNumField = e;
} else if (e.name === "fahrgastrechte-bahn-card-auswahl-geburts-datum") {
bdayField = e;
}
})
fillBcnum(bcNumField);
fillBday(bdayField);
return true;
}
}
const clickContinue = {
name: "clickContinue",
match: () => true,
execute: e => {
const continueButton = document.querySelector('.fahrgastrechte-bahn-card-auswahl button.fahrgastrechte-continue-button');
if (continueButton instanceof Element) {
continueButton.dispatchEvent(new Event('click'));
return true;
}
return false;
}
}
const iWasDelayed = {
name: "iWasDelayed",
match: node => node.classList.contains("antrags-typ-auswahl") && clickThroughForms,
execute: node => {
const delay = node.querySelector('input#antragstyp-verspaetung');
if (delay instanceof HTMLInputElement) {
delay.dispatchEvent(new Event('change'));
return true;
}
return false;
}
}
const moreThan60Minutes = {
name: "moreThan60Minutes",
match: node => node.classList.contains("verspaetungs-auswahl") && clickThroughForms,
execute: node => node.querySelector('#verspaetungstyp-mehr-als-stunde').dispatchEvent(new Event('change'))
}
2023-11-13 20:32:57 +01:00
2023-10-14 16:28:19 +02:00
const continueToForm = {
name: "continueToForm",
match: node => node.classList.contains("verspaetung-bestaetigung") && clickThroughForms,
execute: node => node.querySelector('button.fahrgastrechte-continue-button').dispatchEvent(new Event('click', { bubbles: true }))
}
2023-11-13 20:32:57 +01:00
const enterPersonalData = {
name: "enterPersonalData",
2023-11-13 22:42:42 +01:00
match: node => node.classList.contains("persoenlicheangaben") && hasConfiguredPersonalData,
2023-11-13 20:32:57 +01:00
execute: node => {
browser.storage.sync.get(personalDataConfigKeys).then(foundKeys => {
console.log("storage returned", foundKeys);
//TODO the dropdowns are crazy
// if (foundKeys.keys().contains("addr__appellation")){
// let dropDownSelectList = node.querySelector('.test-name-anrede ul.db-web-select-list');
// }
2023-11-13 22:42:42 +01:00
const configKey_Selector = {
"addr__firstName": ".test-name-vorname input",
"addr__surName": ".test-name-nachname input",
"addr__email": ".persoenlicheangaben__email input",
"addr__street": ".test-adresse-strasse input",
"addr__postcode": ".test-adresse-plz input",
"addr__placename": ".test-adresse-ort input"
}
2023-11-13 20:32:57 +01:00
for (const [k, v] of Object.entries(foundKeys)) {
2023-11-13 22:42:42 +01:00
if (Object.keys(configKey_Selector).includes(k)) {
//TODO WIP this only works on some fields
console.log("filling", configKey_Selector, "with", v);
fillTextInput(node, configKey_Selector[k], v);
} else {
console.log("no selector found for config key", k);
2023-11-13 20:32:57 +01:00
}
}
const continueBtn = document.querySelector(".fahrgastrechte-editable__buttons button.fahrgastrechte-continue-button");
if (continueBtn.querySelector("span span.db-web-button__label").textContent == "OK, weiter" && clickThroughForms) {
continueBtn.dispatchEvent(new Event("click", { bubbles: true }));
}
return true;
})
},
}
const enterPaymentDetails = {
name: "enterPaymentDetails",
2023-11-13 22:42:42 +01:00
match: node => node.classList.contains("entschaedigung") && hasConfiguredBankDetails,
2023-11-13 20:32:57 +01:00
execute: node => {
node.querySelector('#ueberweisung').dispatchEvent(new Event('change'));
browser.storage.sync.get(bankDetailConfigKeys).then(results => {
console.log(results);
for (const [k, v] of Object.entries(results)) {
switch (k) {
case "pymt__iban":
fillTextInput(node, '.test-entschaedigung-iban input', v);
break;
case "pymt__bic":
fillTextInput(node, '.test-entschaedigung-bic input', v);
break;
}
}
})
true
},
}
const defaultStages = [
startClaim, fillData, clickContinue, iWasDelayed, moreThan60Minutes, continueToForm, enterPersonalData, enterPaymentDetails
2023-10-14 16:28:19 +02:00
];
2023-11-13 20:32:57 +01:00
stages = defaultStages;