choose your own adventure
This commit is contained in:
parent
cc7a1ceda5
commit
f796c6fd04
@ -1,6 +1,9 @@
|
||||
"use strict";
|
||||
// Put all the javascript code here, that you want to execute after page load.
|
||||
|
||||
/**
|
||||
* @typedef ("delay"|"nodep"|"abort"|"") DisruptionType
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @typedef {Object} Stage
|
||||
@ -11,9 +14,14 @@
|
||||
*/
|
||||
/**
|
||||
* @type Stage
|
||||
* @todo this can now also contain a dict<DisruptionType, Stage>
|
||||
*/
|
||||
let currentStage;
|
||||
const settings = browser.storage.sync;
|
||||
/**
|
||||
* @type ("delay"|"nodep"|"abort"|"")
|
||||
*/
|
||||
let disruption = "";
|
||||
|
||||
/**
|
||||
*
|
||||
@ -44,22 +52,6 @@ const pressKey = (...keys) => {
|
||||
d(new KeyboardEvent('keyup', { bubbles: true, key: k }));
|
||||
})
|
||||
}
|
||||
/** @param {Node} node */
|
||||
function executeStage(node) {
|
||||
if (node.nodeType === 1) {
|
||||
if (currentStage === undefined) {
|
||||
currentStage = stages.shift();
|
||||
}
|
||||
if (currentStage.match(node)) {
|
||||
console.log(currentStage.name, "matched: ", node);
|
||||
console.log(currentStage.name, currentStage.execute(node) ? "executed" : "execution failed");
|
||||
nextStage();
|
||||
} else {
|
||||
console.log(currentStage.name, "did not match: ", mutation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let stages;
|
||||
const personalDataConfigKeys = [
|
||||
"addr__appellation", "addr__title", "addr__firstName", "addr__surName",
|
||||
@ -88,6 +80,19 @@ function processMutations(mutationList, observer) {
|
||||
if (currentStage === undefined) {
|
||||
currentStage = stages.shift();
|
||||
}
|
||||
if (!("name" in currentStage)){
|
||||
// stages always have a `name`, so this must be the disruption type split
|
||||
if (disruption in currentStage){
|
||||
stages.unshift(...currentStage[disruption]);
|
||||
currentStage = stages.shift();
|
||||
} else if (disruption == "") {
|
||||
// no default action - skip to personal data stuff
|
||||
currentStage = stages.shift();
|
||||
//TODO sniff action and provide field jumps instead
|
||||
} else {
|
||||
console.log("this Stage is invalid, aborting", currentStage);
|
||||
}
|
||||
}
|
||||
for (const mutation of mutationList) {
|
||||
if ('expects' in currentStage) {
|
||||
if (currentStage.expects == 'mutation') {
|
||||
@ -116,7 +121,6 @@ function processMutations(mutationList, observer) {
|
||||
|
||||
}
|
||||
}
|
||||
let clickThroughForms;
|
||||
let hasConfiguredBankDetails, hasConfiguredPersonalData;
|
||||
let observer = new MutationObserver(processMutations);
|
||||
function nextStage() {
|
||||
@ -129,9 +133,9 @@ function nextStage() {
|
||||
}
|
||||
const addObserver = () => {
|
||||
settings.get(
|
||||
['autocontinue', 'enable'].concat(personalDataConfigKeys, bankDetailConfigKeys)
|
||||
['enable', 'defaultAction'].concat(personalDataConfigKeys, bankDetailConfigKeys)
|
||||
).then(userSettings => {
|
||||
clickThroughForms = !!userSettings.autocontinue;
|
||||
disruption = userSettings.defaultAction || "";
|
||||
hasConfiguredPersonalData = Object.keys(userSettings).filter(k => personalDataConfigKeys.includes(k)).length > 0;
|
||||
hasConfiguredBankDetails = Object.keys(userSettings).filter(k => bankDetailConfigKeys.includes(k)).length > 0;
|
||||
if (!!userSettings.enable) {
|
||||
@ -231,9 +235,21 @@ const clickContinue = {
|
||||
|
||||
}
|
||||
|
||||
//TODO construction zone
|
||||
const sniffDisruption = {
|
||||
name: "sniffDisruption",
|
||||
match: node => {
|
||||
//delay -> .verspaetungs-auswahl.fahrgastrechte-page__section.test-current-section
|
||||
//nodep -> .fahrplan...., .antrags-typ-auswahl:children("input[name=radioAntragsTyp]"):id(#antragstyp-nicht-angetreten):has-siblings(.db-web-radio-button-container__radio-button-icon--checked)
|
||||
//abort -> .fahrplan...., ...#antragstyp-abgebrochen, An welchem Bahnhof? -> .fahrgastrechte-page__section:has-child(.fahrgastrechte-editable.fahrgastrechte-bahnhof.abbruchbahnhof)
|
||||
// Weitere Kosten? (.kosten-abfrage.f-p__s.t-c-s:has_child(.db-web-radio-button-container.kosten-abfrage__radio))
|
||||
},
|
||||
execute: () => true
|
||||
}
|
||||
|
||||
const iWasDelayed = {
|
||||
name: "iWasDelayed",
|
||||
match: node => node.classList.contains("antrags-typ-auswahl") && clickThroughForms,
|
||||
match: node => node.classList.contains("antrags-typ-auswahl"),
|
||||
execute: node => {
|
||||
const delay = $$(node, 'input#antragstyp-verspaetung');
|
||||
if (delay instanceof HTMLInputElement) {
|
||||
@ -246,19 +262,21 @@ const iWasDelayed = {
|
||||
|
||||
const moreThan60Minutes = {
|
||||
name: "moreThan60Minutes",
|
||||
match: node => node.classList.contains("verspaetungs-auswahl") && clickThroughForms,
|
||||
execute: node => node.querySelector('#verspaetungstyp-mehr-als-stunde').dispatchEvent(new Event('change'))
|
||||
match: node => node.classList.contains("verspaetungs-auswahl"),
|
||||
execute: node => {
|
||||
return node.querySelector('#verspaetungstyp-mehr-als-stunde').dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
|
||||
const continueToForm = {
|
||||
name: "continueToForm",
|
||||
match: node => node.classList.contains("verspaetung-bestaetigung") && clickThroughForms,
|
||||
match: node => node.classList.contains("verspaetung-bestaetigung"),
|
||||
execute: node => $$(node, 'button.fahrgastrechte-continue-button').dispatchEvent(_clickEv())
|
||||
}
|
||||
|
||||
const focusDepartureInput = {
|
||||
name: "focusDepartureInput",
|
||||
match: node => node.classList.contains("fahrplan") && clickThroughForms,
|
||||
match: node => node.classList.contains("fahrplan"),
|
||||
execute: node => {
|
||||
const depInput = $$(node, '.fahrplan__start .fahrplan__haltestelle input');
|
||||
const obs = new IntersectionObserver((entries, intObserver) => {
|
||||
@ -274,7 +292,7 @@ const focusDepartureInput = {
|
||||
|
||||
const jumpToTimeInput = {
|
||||
name: "jumpToTimeInput",
|
||||
match: node => node.classList.contains("ankunft-zeit") && clickThroughForms,
|
||||
match: node => node.classList.contains("ankunft-zeit"),
|
||||
execute: node => {
|
||||
$$(node, '#fahrgastrechte-ankunft-uhrzeit--db-web-text-input').focus();
|
||||
return true;
|
||||
@ -426,8 +444,8 @@ const enterPaymentDetails = {
|
||||
}
|
||||
const defaultStages = [
|
||||
startClaim, fillData, clickContinue,
|
||||
iWasDelayed, moreThan60Minutes, continueToForm,
|
||||
focusDepartureInput, jumpToTimeInput,
|
||||
{"delay": [iWasDelayed, moreThan60Minutes, continueToForm,
|
||||
focusDepartureInput, jumpToTimeInput], "nodep": [], "abort": []},
|
||||
activateAppellationDropdown, enterAppellationAndActivateTitleDropdown,
|
||||
enterTitleAndActivateCountryDropdown, enterCountry,
|
||||
enterTextPersonalData, /* continueToPayout, */ enterPaymentDetails
|
||||
|
@ -16,9 +16,13 @@
|
||||
<input name="enable" id="enable" type="checkbox" />
|
||||
</label>
|
||||
<label class="item">
|
||||
<span class="fh">Skip questionnaire</span>
|
||||
<input name="autocontinue" id="autocontinue" type="checkbox" />
|
||||
<span class="sh">Automatically answer "I was delayed, by more than 60 minutes."</span>
|
||||
<span class="fh">Default action</span>
|
||||
<select class="default_action" id="default_action">
|
||||
<option value="">None</option>
|
||||
<option value="delay">I arrived >60 min late</option>
|
||||
<option value="nodep">I did not start the trip</option>
|
||||
<option value="abort">I returned home</option>
|
||||
</select>
|
||||
</label>
|
||||
</fieldset>
|
||||
<button id="all-get-from-profile">Get my personal data from my profile</button>
|
||||
|
@ -75,8 +75,8 @@ async function saveOptions(ev) {
|
||||
putError("Please enter a birthday.");
|
||||
return;
|
||||
}
|
||||
let autoContinue = this.querySelector('#autocontinue').checked;
|
||||
let enable = this.querySelector('#enable').checked;
|
||||
let defaultAction = this.querySelector('#default_action').value;
|
||||
let title = this.querySelector('#title').value;
|
||||
let title_addl = this.querySelector('#title_addl').value;
|
||||
let firstName = this.querySelector('#firstname').value;
|
||||
@ -95,8 +95,8 @@ async function saveOptions(ev) {
|
||||
let options = {
|
||||
bcnum: bcNum,
|
||||
bday: bDay,
|
||||
autocontinue: autoContinue,
|
||||
enable: enable,
|
||||
defaultAction: defaultAction,
|
||||
addr__appellation: title,
|
||||
addr__title: title_addl,
|
||||
addr__firstName: firstName,
|
||||
@ -131,7 +131,7 @@ async function restoreOptions() {
|
||||
document.querySelector('#enable').checked = settings.enable || true;
|
||||
document.querySelector("#bcnum").value = settings.bcnum || "";
|
||||
document.querySelector("#birthday").value = settings.bday || "";
|
||||
document.querySelector("#autocontinue").checked = settings.autocontinue || false;
|
||||
document.querySelector("#default_action").value = settings.defaultAction || "";
|
||||
document.querySelector('#title').value = settings.addr__appellation || "";
|
||||
document.querySelector('#title_addl').value = settings.addr__title || "";
|
||||
document.querySelector('#firstname').value = settings.addr__firstName || "";
|
||||
|
Loading…
Reference in New Issue
Block a user