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;
|