OS2.ergebnisse.user.js: Unterschied zwischen den Versionen
SLC (Diskussion | Beiträge) (Update Version 0.20 (Optionen auch auf der Seite, https://)) |
SLC (Diskussion | Beiträge) (Update Version 0.21 (Speicherfunktionen, Land- und Liga-Nummern)) |
||
| Zeile 2: | Zeile 2: | ||
// @name OS2.ergebnisse | // @name OS2.ergebnisse | ||
// @namespace http://os.ongapo.com/ | // @namespace http://os.ongapo.com/ | ||
// @version 0. | // @version 0.21 | ||
// @copyright 2016+ | // @copyright 2016+ | ||
// @author Sven Loges (SLC) | // @author Sven Loges (SLC) | ||
| Zeile 105: | Zeile 105: | ||
'RST' : "reset options" | 'RST' : "reset options" | ||
}; | }; | ||
const __OPTMEM = { | |||
'normal' : { | |||
'Name' : "Session", | |||
'Value' : sessionStorage, | |||
'Display' : "sessionStorage", | |||
'Prefix' : 'run' | |||
}, | |||
'unbegrenzt' : { | |||
'Name' : "Browser", | |||
'Value' : localStorage, | |||
'Display' : "localStorage", | |||
'Prefix' : 'run' | |||
}, | |||
'inaktiv' : { | |||
'Name' : "inaktiv", | |||
'Value' : undefined, | |||
'Display' : "", | |||
'Prefix' : "" | |||
} | |||
}; | |||
let myOptMem = __OPTMEM.normal; | |||
// Moegliche Optionen (hier die Standardwerte editieren oder ueber das Benutzermenu setzen): | // Moegliche Optionen (hier die Standardwerte editieren oder ueber das Benutzermenu setzen): | ||
| Zeile 126: | Zeile 149: | ||
'Hotkey' : 'O', | 'Hotkey' : 'O', | ||
'FormLabel' : "" | 'FormLabel' : "" | ||
}, | |||
'storage' : { // Browserspeicher fuer die Klicks auf Optionen | |||
'Name' : "storage", | |||
'Type' : __OPTTYPES.MC, | |||
'ValType' : "String", | |||
'Choice' : Object.keys(__OPTMEM), | |||
'Action' : __OPTACTION.NXT, | |||
'Label' : "Speicher: $", | |||
'Hotkey' : 'c', | |||
'FormLabel' : "Speicher:|$" | |||
}, | |||
'oldStorage' : { // Vorheriger Browserspeicher fuer die Klicks auf Optionen | |||
'Name' : "oldStorage", | |||
'Type' : __OPTTYPES.SD, | |||
'AutoReset' : true, | |||
'Hidden' : true | |||
}, | }, | ||
'showForm' : { // Optionen auf der Webseite (true = anzeigen, false = nicht anzeigen) | 'showForm' : { // Optionen auf der Webseite (true = anzeigen, false = nicht anzeigen) | ||
| Zeile 245: | Zeile 284: | ||
function setNextStored(arr, name, value, reload = true, serial = false) { | function setNextStored(arr, name, value, reload = true, serial = false) { | ||
return setStored(name, getNextValue(arr, value), reload, serial); | return setStored(name, getNextValue(arr, value), reload, serial); | ||
} | |||
// Kompatibilitaetsfunktion: Testet, ob der uebergebene Speicher genutzt werden kann | |||
// storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv | |||
function canUseStorage(storage = undefined) { | |||
const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); | |||
const __MEMORY = __STORAGE.Value; | |||
let ret = false; | |||
if (__MEMORY !== undefined) { | |||
const __TESTITEM = 'canUseStorageTest'; | |||
const __TEST = Math.random().toString(); | |||
__MEMORY.setItem(__TESTITEM, __TEST); | |||
ret = (__MEMORY.getItem(__TESTITEM) === __TEST); | |||
__MEMORY.removeItem(__TESTITEM); | |||
} | |||
console.log("canUseStorage(" + __STORAGE.Name + ") = " + ret); | |||
return ret; | |||
} | } | ||
// Fuehrt die in einem Storage gespeicherte Operation aus | // Fuehrt die in einem Storage gespeicherte Operation aus | ||
// optSet: Set mit den Optionen | // optSet: Set mit den Optionen | ||
// | // storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv | ||
function runStored(optSet, | function runStored(optSet, storage = undefined) { | ||
const __STORAGE = ( | const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); | ||
const | const __MEMORY = __STORAGE.Value; | ||
const __RUNPREFIX = __STORAGE.Prefix; | |||
if ( | if (__MEMORY !== undefined) { | ||
const | const __GETITEM = function(item) { | ||
return __MEMORY.getItem(__RUNPREFIX + item); | |||
}; | |||
const __DELITEM = function(item) { | |||
return __MEMORY.removeItem(__RUNPREFIX + item); | |||
}; | |||
const __CMD = ((__MEMORY !== undefined) ? __GETITEM('cmd') : undefined); | |||
try { | if (__CMD !== undefined) { | ||
const __KEY = __GETITEM('key'); | |||
let value = __GETITEM('val'); | |||
try { | |||
value = JSON.parse(value); | |||
} catch (ex) { | |||
console.error("runStored(): " + __CMD + " '" + __KEY + "' hat illegalen Wert '" + value + "'"); | |||
// ... meist kann man den String selber aber speichern, daher kein "return"... | |||
} | |||
const __VAL = value; | |||
switch (__OPTACTION[__CMD]) { | |||
case __OPTACTION.SET : console.log("SET '" + __KEY + "' " + __VAL); | |||
setStored(__KEY, __VAL, false, false); | |||
break; | |||
case __OPTACTION.NXT : console.log("SETNEXT '" + __KEY + "' " + __VAL); | |||
//setNextStored(__CONFIG.Choice, __KEY, __VAL, false, false); | |||
setStored(__KEY, __VAL, false, false); | |||
break; | |||
case __OPTACTION.RST : console.log("RESET"); | |||
resetOptions(optSet, false); | |||
break; | |||
default : break; | |||
} | |||
} | } | ||
__DELITEM('cmd'); | |||
__DELITEM('key'); | |||
__DELITEM('val'); | |||
} | } | ||
} | } | ||
| Zeile 530: | Zeile 601: | ||
return optSet; | return optSet; | ||
} | |||
// Initialisiert die gesetzten Optionen und den Speicher und laedt die Optionen zum Start | |||
// optConfig: Konfiguration der Optionen | |||
// optSet: Platz fuer die gesetzten Optionen | |||
// return Gefuelltes Objekt mit den gesetzten Optionen | |||
function startOptions(optConfig, optSet = undefined) { | |||
const __NORMAL = 'normal'; | |||
optSet = initOptions(optConfig, optSet); | |||
// Memory Storage fuer vorherige Speicherung... | |||
const __OLDOPT = optSet.oldStorage; | |||
const __OLDSTORAGE = loadOption(getOpt(__OLDOPT), true); | |||
myOptMem = __OPTMEM[getValue(__OLDSTORAGE, __NORMAL)]; | |||
runStored(optSet); | |||
loadOptions(optSet); | |||
// Memory Storage fuer naechste Speicherung... | |||
const __STORAGE = getOptValue(optSet.storage, __NORMAL); | |||
const __NEWSTORAGE = setOpt(__OLDOPT, __STORAGE, false); | |||
if (! canUseStorage(myOptMem = __OPTMEM[getValue(__NEWSTORAGE, __NORMAL)])) { | |||
const __INAKTIV = 'inaktiv'; | |||
if (__NEWSTORAGE !== __INAKTIV) { | |||
setOpt(__OLDOPT, __INAKTIV, false); | |||
myOptMem = __OPTMEM[__INAKTIV]; | |||
} | |||
} | |||
return optSet; | |||
} | |||
// Installiert die Visualisierung und Steuerung der Optionen | |||
// optSet: Platz fuer die gesetzten Optionen | |||
// optParams: Eventuell notwendige Parameter zur Initialisierung | |||
// 'hideMenu': Optionen werden zwar geladen und genutzt, tauchen aber nicht im Benutzermenu auf | |||
// 'menuAnchor': Startpunkt fuer das Optionsmenu auf der Seite | |||
// 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) | |||
// 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) | |||
// 'formWidth': Anzahl der Elemente pro Zeile | |||
// 'formBreak': Elementnummer des ersten Zeilenumbruchs | |||
function showOptions(optSet = undefined, optParams = { 'hideMenu' : false }) { | |||
if (! optParams.hideMenu) { | |||
buildMenu(optSet); | |||
} | |||
if ((optParams.menuAnchor !== undefined) && (myOptMem !== __OPTMEM.inaktiv)) { | |||
buildForm(optParams.menuAnchor, optSet, optParams); | |||
} | |||
} | } | ||
| Zeile 569: | Zeile 691: | ||
function setNextOpt(opt, value = undefined, reload = true) { | function setNextOpt(opt, value = undefined, reload = true) { | ||
const __CONFIG = getOptConfig(opt); | const __CONFIG = getOptConfig(opt); | ||
return setOpt(opt, getNextOpt(opt, | return setOpt(opt, getNextOpt(opt, value), reload); | ||
} | } | ||
| Zeile 680: | Zeile 801: | ||
// name: Neu zu setzender Name (Speicheradresse) | // name: Neu zu setzender Name (Speicheradresse) | ||
// reload: Wert nachladen statt beizubehalten | // reload: Wert nachladen statt beizubehalten | ||
// force: Laedt auch Optionen mit 'AutoReset'-Attribut | |||
// return Umbenannte Option | // return Umbenannte Option | ||
function renameOption(opt, name, reload = false) { | function renameOption(opt, name, reload = false, force = false) { | ||
const __NAME = getOptName(opt); | const __NAME = getOptName(opt); | ||
| Zeile 690: | Zeile 812: | ||
if (reload) { | if (reload) { | ||
loadOption(opt); | loadOption(opt, force); | ||
} | } | ||
} | } | ||
| Zeile 698: | Zeile 820: | ||
// Setzt die Optionen in optSet auf die "Werkseinstellungen" des Skripts | // Setzt die Optionen in optSet auf die "Werkseinstellungen" des Skripts | ||
// optSet: Gesetzte Optionen | |||
// reload: Seite mit "Werkseinstellungen" neu laden | // reload: Seite mit "Werkseinstellungen" neu laden | ||
function resetOptions(optSet, reload = true) { | function resetOptions(optSet, reload = true) { | ||
// Alle (nicht 'Permanent') gesetzten Optionen entfernen... | // Alle (nicht 'Permanent') gesetzten Optionen entfernen... | ||
deleteOptions(optSet, false, | deleteOptions(optSet, false, ! reload); | ||
if (reload) { | if (reload) { | ||
| Zeile 727: | Zeile 849: | ||
// return Gefuelltes Objekt mit den gesetzten Optionen | // return Gefuelltes Objekt mit den gesetzten Optionen | ||
function buildOptions(optConfig, optSet = undefined, optParams = { 'hideMenu' : false }) { | function buildOptions(optConfig, optSet = undefined, optParams = { 'hideMenu' : false }) { | ||
optSet = | optSet = startOptions(optConfig, optSet); | ||
showOptions(optSet, optParams); | |||
return optSet; | return optSet; | ||
| Zeile 883: | Zeile 996: | ||
// value: Ggfs. zu setzender Wert | // value: Ggfs. zu setzender Wert | ||
// serial: Serialization fuer String-Werte (Select, Textarea) | // serial: Serialization fuer String-Werte (Select, Textarea) | ||
// storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv | |||
// return String mit dem (reinen) Funktionsaufruf | // return String mit dem (reinen) Funktionsaufruf | ||
function getFormAction(opt, isAlt = false, value = undefined, serial = undefined) { | function getFormAction(opt, isAlt = false, value = undefined, serial = undefined, storage = undefined) { | ||
const | const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); | ||
const | const __MEMORY = __STORAGE.Value; | ||
const __MEMSTR = __STORAGE.Display; | |||
const __RUNPREFIX = __STORAGE.Prefix; | |||
if (__MEMORY !== undefined) { | |||
const __RELOAD = "window.location.reload()"; | |||
const __SETITEM = function(item, val, quotes = true) { | |||
return (__MEMSTR + ".setItem('" + __RUNPREFIX + item + "', " + (quotes ? "'" + val + "'" : val) + "),"); | |||
}; | |||
const __SETITEMS = function(cmd, key = undefined, val = undefined) { | |||
return ('(' + __SETITEM('cmd', cmd) + ((key === undefined) ? "" : | |||
__SETITEM('key', key) + __SETITEM('val', val, false)) + __RELOAD + ')'); | |||
}; | |||
const __CONFIG = getOptConfig(opt); | |||
const __SERIAL = getValue(serial, getValue(__CONFIG.Serial, false)); | |||
const __THISVAL = ((__CONFIG.ValType === "String") ? "'\\x22' + this.value + '\\x22'" : "this.value"); | |||
const __TVALUE = getValue(__CONFIG.ValType, __THISVAL, "new " + __CONFIG.ValType + '(' + __THISVAL + ')'); | |||
const __VALSTR = ((value !== undefined) ? JSON.stringify(value) : __SERIAL ? "JSON.stringify(" + __TVALUE + ')' : __TVALUE); | |||
const __ACTION = (isAlt ? getValue(__CONFIG.AltAction, __CONFIG.Action) : __CONFIG.Action); | |||
if (__ACTION !== undefined) { | |||
switch (__ACTION) { | |||
case __OPTACTION.SET : //return "doActionSet('" + getOptName(opt) + "', " + getNextOpt(opt, __VALSTR) + ')'; | |||
return __SETITEMS('SET', getOptName(opt), __VALSTR); | |||
case __OPTACTION.NXT : //return "doActionNxt('" + getOptName(opt) + "', " + getNextOpt(opt, __VALSTR) + ')'; | |||
return __SETITEMS('NXT', getOptName(opt), __VALSTR); | |||
case __OPTACTION.RST : //return "doActionRst()"; | |||
return __SETITEMS('RST'); | |||
default : break; | |||
} | |||
} | } | ||
} | } | ||
| Zeile 914: | Zeile 1.042: | ||
// type: Event-Typ fuer <input>, z.B. "click" fuer "onclick=" | // type: Event-Typ fuer <input>, z.B. "click" fuer "onclick=" | ||
// serial: Serialization fuer String-Werte (Select, Textarea) | // serial: Serialization fuer String-Werte (Select, Textarea) | ||
// storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv | |||
// return String mit dem (reinen) Funktionsaufruf | // return String mit dem (reinen) Funktionsaufruf | ||
function getFormActionEvent(opt, isAlt = false, value = undefined, type = "click", serial = undefined) { | function getFormActionEvent(opt, isAlt = false, value = undefined, type = "click", serial = undefined, storage = undefined) { | ||
const __ACTION = getFormAction(opt, isAlt, value, serial); | const __ACTION = getFormAction(opt, isAlt, value, serial, storage); | ||
return getValue(__ACTION, "", ' on' + type + '="' + __ACTION + '"'); | return getValue(__ACTION, "", ' on' + type + '="' + __ACTION + '"'); | ||
| Zeile 1.152: | Zeile 1.281: | ||
function procErgebnisse() { | function procErgebnisse() { | ||
buildOptions(__OPTCONFIG, __OPTSET, { | buildOptions(__OPTCONFIG, __OPTSET, { | ||
'menuAnchor' : getTable(0, "div") | 'menuAnchor' : getTable(0, "div"), | ||
'formWidth' : 2 | |||
}); | }); | ||
Aktuelle Version vom 5. Oktober 2016, 04:46 Uhr
// ==UserScript== // @name OS2.ergebnisse // @namespace http://os.ongapo.com/ // @version 0.21 // @copyright 2016+ // @author Sven Loges (SLC) // @description Aktiviert als Standard die Option "Ergebnisse anzeigen" fuer Online Soccer 2.0 // @include http*://os.ongapo.com/ls.php // @include http*://os.ongapo.com/ls.php?* // @include http*://os.ongapo.com/lp.php // @include http*://os.ongapo.com/lp.php?* // @include http*://os.ongapo.com/oseq.php // @include http*://os.ongapo.com/oseq.php?* // @include http*://os.ongapo.com/ose.php // @include http*://os.ongapo.com/ose.php?* // @include http*://os.ongapo.com/oscq.php // @include http*://os.ongapo.com/oscq.php?* // @include http*://os.ongapo.com/oschr.php // @include http*://os.ongapo.com/oschr.php?* // @include http*://os.ongapo.com/osczr.php // @include http*://os.ongapo.com/osczr.php?* // @include http*://os.ongapo.com/oscfr.php // @include http*://os.ongapo.com/oscfr.php?* // @include http*://os.ongapo.com/zer.php // @include http*://os.ongapo.com/zer.php?* // @include http*://www.os.ongapo.com/ls.php // @include http*://www.os.ongapo.com/ls.php?* // @include http*://www.os.ongapo.com/lp.php // @include http*://www.os.ongapo.com/lp.php?* // @include http*://www.os.ongapo.com/oseq.php // @include http*://www.os.ongapo.com/oseq.php?* // @include http*://www.os.ongapo.com/ose.php // @include http*://www.os.ongapo.com/ose.php?* // @include http*://www.os.ongapo.com/oscq.php // @include http*://www.os.ongapo.com/oscq.php?* // @include http*://www.os.ongapo.com/oschr.php // @include http*://www.os.ongapo.com/oschr.php?* // @include http*://www.os.ongapo.com/osczr.php // @include http*://www.os.ongapo.com/osczr.php?* // @include http*://www.os.ongapo.com/oscfr.php // @include http*://www.os.ongapo.com/oscfr.php?* // @include http*://www.os.ongapo.com/zer.php // @include http*://www.os.ongapo.com/zer.php?* // @include http*://online-soccer.eu/ls.php // @include http*://online-soccer.eu/ls.php?* // @include http*://online-soccer.eu/lp.php // @include http*://online-soccer.eu/lp.php?* // @include http*://online-soccer.eu/oseq.php // @include http*://online-soccer.eu/oseq.php?* // @include http*://online-soccer.eu/ose.php // @include http*://online-soccer.eu/ose.php?* // @include http*://online-soccer.eu/oscq.php // @include http*://online-soccer.eu/oscq.php?* // @include http*://online-soccer.eu/oschr.php // @include http*://online-soccer.eu/oschr.php?* // @include http*://online-soccer.eu/osczr.php // @include http*://online-soccer.eu/osczr.php?* // @include http*://online-soccer.eu/oscfr.php // @include http*://online-soccer.eu/oscfr.php?* // @include http*://online-soccer.eu/zer.php // @include http*://online-soccer.eu/zer.php?* // @include http*://www.online-soccer.eu/ls.php // @include http*://www.online-soccer.eu/ls.php?* // @include http*://www.online-soccer.eu/lp.php // @include http*://www.online-soccer.eu/lp.php?* // @include http*://www.online-soccer.eu/oseq.php // @include http*://www.online-soccer.eu/oseq.php?* // @include http*://www.online-soccer.eu/ose.php // @include http*://www.online-soccer.eu/ose.php?* // @include http*://www.online-soccer.eu/oscq.php // @include http*://www.online-soccer.eu/oscq.php?* // @include http*://www.online-soccer.eu/oschr.php // @include http*://www.online-soccer.eu/oschr.php?* // @include http*://www.online-soccer.eu/osczr.php // @include http*://www.online-soccer.eu/osczr.php?* // @include http*://www.online-soccer.eu/oscfr.php // @include http*://www.online-soccer.eu/oscfr.php?* // @include http*://www.online-soccer.eu/zer.php // @include http*://www.online-soccer.eu/zer.php?* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_registerMenuCommand // ==/UserScript==
// ECMAScript 6: Erlaubt 'const', 'let', ... /* jshint esnext: true */ /* jshint moz: true */
// ==================== Konfigurations-Abschnitt fuer Optionen ====================
// Options-Typen const __OPTTYPES = {
'MC' : "multiple choice", 'SW' : "switch", 'TF' : "true/false", 'SD' : "simple data", 'SI' : "simple option"
};
// Options-Typen const __OPTACTION = {
'SET' : "set option value", 'NXT' : "set next option value", 'RST' : "reset options"
};
const __OPTMEM = {
'normal' : {
'Name' : "Session",
'Value' : sessionStorage,
'Display' : "sessionStorage",
'Prefix' : 'run'
},
'unbegrenzt' : {
'Name' : "Browser",
'Value' : localStorage,
'Display' : "localStorage",
'Prefix' : 'run'
},
'inaktiv' : {
'Name' : "inaktiv",
'Value' : undefined,
'Display' : "",
'Prefix' : ""
}
};
let myOptMem = __OPTMEM.normal;
// Moegliche Optionen (hier die Standardwerte editieren oder ueber das Benutzermenu setzen): const __OPTCONFIG = {
'showErgs' : { // Standardeinstellung der Ergebnisanzeige
'Name' : "showErgs",
'Type' : __OPTTYPES.SW,
'Default' : true,
'Action' : __OPTACTION.NXT,
'Label' : "Ergebnisse anzeigen",
'Hotkey' : 'E',
'AltLabel' : "Keine Ergebnisse",
'AltHotkey' : 'K',
'FormLabel' : "Ergebnisse anzeigen"
},
'reset' : { // Optionen auf die "Werkseinstellungen" zuruecksetzen
'Name' : "reset",
'Type' : __OPTTYPES.SI,
'Action' : __OPTACTION.RST,
'Label' : "Standard-Optionen",
'Hotkey' : 'O',
'FormLabel' : ""
},
'storage' : { // Browserspeicher fuer die Klicks auf Optionen
'Name' : "storage",
'Type' : __OPTTYPES.MC,
'ValType' : "String",
'Choice' : Object.keys(__OPTMEM),
'Action' : __OPTACTION.NXT,
'Label' : "Speicher: $",
'Hotkey' : 'c',
'FormLabel' : "Speicher:|$"
},
'oldStorage' : { // Vorheriger Browserspeicher fuer die Klicks auf Optionen
'Name' : "oldStorage",
'Type' : __OPTTYPES.SD,
'AutoReset' : true,
'Hidden' : true
},
'showForm' : { // Optionen auf der Webseite (true = anzeigen, false = nicht anzeigen)
'Name' : "showForm",
'Type' : __OPTTYPES.SW,
'FormType' : __OPTTYPES.SI,
'Permanent' : true,
'Default' : false,
'Action' : __OPTACTION.NXT,
'Label' : "Optionen anzeigen",
'Hotkey' : 'a',
'AltLabel' : "Optionen verbergen",
'AltHotkey' : 'v',
'FormLabel' : ""
}
};
// ==================== Invarianter Abschnitt fuer Optionen ====================
// ==================== Abschnitt fuer diverse Utilities ====================
// Gibt einen Wert zurueck. Ist dieser nicht definiert, wird ein Alternativwert geliefert // value: Ein Wert. Ist dieser nicht undefined, wird er zurueckgeliefert // defValue: Default-Wert fuer den Fall, dass nichts gesetzt ist // retValue: Falls definiert, Rueckgabe-Wert fuer den Fall, dass value nicht undefined ist // return Der Wert. Sind weder value noch defValue definiert, dann undefined function getValue(value, defValue = undefined, retValue = undefined) {
return (value === undefined) ? defValue : (retValue === undefined) ? value : retValue;
}
// Gibt einen Wert zurueck. Ist dieser nicht definiert, wird ein Alternativwert geliefert // value: Ein Wert. Ist dieser definiet und in den Grenzen, wird er zurueckgeliefert // minValue: Untere Grenze fuer den Wert, falls angegeben // minValue: Obere Grenze fuer den Wert, falls angegeben // defValue: Default-Wert fuer den Fall, dass nichts gesetzt ist oder der Wert ausserhalb liegt // return Der Wert. Sind weder value (in den Grenzen) noch defValue definiert, dann undefined function getValueIn(value, minValue = undefined, maxValue = undefined, defValue = undefined) {
const __VALUE = getValue(value, defValue);
if ((minValue !== undefined) && (__VALUE < minValue)) {
return defValue;
}
if ((maxValue !== undefined) && (__VALUE > maxValue)) {
return defValue;
}
return __VALUE;
}
// Ermittelt den naechsten Wert aus einer Array-Liste // arr: Array-Liste mit den moeglichen Werte // value: Vorher gesetzter Wert // return Naechster Wert in der Array-Liste function getNextValue(arr, value) {
const __POS = arr.indexOf(value) + 1;
return arr[getValueIn(__POS, 0, arr.length - 1, 0)];
}
// Speichert einen beliebiegen (strukturierten) Wert unter einem Namen ab // name: GM_setValue-Name, unter dem die Daten gespeichert werden // value: Beliebiger (strukturierter) Wert // return String-Darstellung des Wertes function serialize(name, value) {
const __STREAM = (value !== undefined) ? JSON.stringify(value) : value;
console.log(name + " >> " + __STREAM);
GM_setValue(name, __STREAM);
return __STREAM;
}
// Holt einen beliebiegen (strukturierter) Wert unter einem Namen zurueck // name: GM_setValue-Name, unter dem die Daten gespeichert werden // defValue: Default-Wert fuer den Fall, dass nichts gespeichert ist // return Objekt, das unter dem Namen gespeichert war function deserialize(name, defValue = undefined) {
const __STREAM = GM_getValue(name, defValue);
console.log(name + " << " + __STREAM);
if ((__STREAM !== undefined) && (__STREAM.length !== 0)) {
try {
return JSON.parse(__STREAM);
} catch (ex) {
console.error(name + ": " + ex.message);
}
}
return undefined;
}
// Setzt eine Option dauerhaft und laedt die Seite neu // name: Name der Option als Speicherort // value: Zu setzender Wert // reload: Seite mit neuem Wert neu laden // return Gespeicherter Wert fuer setOptValue() function setStored(name, value, reload = true, serial = false) {
if (serial) {
serialize(name, value);
} else {
GM_setValue(name, value);
}
if (reload) {
window.location.reload();
}
return value;
}
// Setzt den naechsten Wert aus einer Array-Liste als Option // arr: Array-Liste mit den moeglichen Optionen // name: Name der Option als Speicherort // value: Vorher gesetzter Wert // reload: Seite mit neuem Wert neu laden // return Gespeicherter Wert fuer setOptValue() function setNextStored(arr, name, value, reload = true, serial = false) {
return setStored(name, getNextValue(arr, value), reload, serial);
}
// Kompatibilitaetsfunktion: Testet, ob der uebergebene Speicher genutzt werden kann // storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv function canUseStorage(storage = undefined) {
const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); const __MEMORY = __STORAGE.Value; let ret = false;
if (__MEMORY !== undefined) {
const __TESTITEM = 'canUseStorageTest';
const __TEST = Math.random().toString();
__MEMORY.setItem(__TESTITEM, __TEST);
ret = (__MEMORY.getItem(__TESTITEM) === __TEST);
__MEMORY.removeItem(__TESTITEM);
}
console.log("canUseStorage(" + __STORAGE.Name + ") = " + ret);
return ret;
}
// Fuehrt die in einem Storage gespeicherte Operation aus // optSet: Set mit den Optionen // storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv function runStored(optSet, storage = undefined) {
const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); const __MEMORY = __STORAGE.Value; const __RUNPREFIX = __STORAGE.Prefix;
if (__MEMORY !== undefined) {
const __GETITEM = function(item) {
return __MEMORY.getItem(__RUNPREFIX + item);
};
const __DELITEM = function(item) {
return __MEMORY.removeItem(__RUNPREFIX + item);
};
const __CMD = ((__MEMORY !== undefined) ? __GETITEM('cmd') : undefined);
if (__CMD !== undefined) {
const __KEY = __GETITEM('key');
let value = __GETITEM('val');
try {
value = JSON.parse(value);
} catch (ex) {
console.error("runStored(): " + __CMD + " '" + __KEY + "' hat illegalen Wert '" + value + "'");
// ... meist kann man den String selber aber speichern, daher kein "return"...
}
const __VAL = value;
switch (__OPTACTION[__CMD]) {
case __OPTACTION.SET : console.log("SET '" + __KEY + "' " + __VAL);
setStored(__KEY, __VAL, false, false);
break;
case __OPTACTION.NXT : console.log("SETNEXT '" + __KEY + "' " + __VAL);
//setNextStored(__CONFIG.Choice, __KEY, __VAL, false, false);
setStored(__KEY, __VAL, false, false);
break;
case __OPTACTION.RST : console.log("RESET");
resetOptions(optSet, false);
break;
default : break;
}
}
__DELITEM('cmd');
__DELITEM('key');
__DELITEM('val');
}
}
// Gibt eine Option sicher zurueck // opt: Config und Value der Option, ggfs. undefined // defOpt: Rueckgabewert, falls undefined // return Daten zur Option (oder defOpt) function getOpt(opt, defOpt = { }) {
return getValue(opt, defOpt);
}
// Gibt eine Option sicher zurueck (Version mit Key) // optSet: Platz fuer die gesetzten Optionen (und Config) // item: Key der Option // defOpt: Rueckgabewert, falls nicht zu finden // return Daten zur Option (oder defOpt) function getOptByName(optSet, item, defOpt = { }) {
if ((optSet !== undefined) && (item !== undefined)) {
return getOpt(optSet[item], defOpt);
} else {
return defOpt;
}
}
// Gibt die Konfigurationsdaten einer Option zurueck // opt: Config und Value der Option // defConfig: Rueckgabewert, falls Config nicht zu finden // return Konfigurationsdaten der Option function getOptConfig(opt, defConfig = { }) {
return getValue(getOpt(opt).Config, defConfig);
}
// Setzt den Namen einer Option // opt: Config und Value der Option // name: Zu setzender Name der Option // reload: Seite mit neuem Wert neu laden // return Gesetzter Name der Option function setOptName(opt, name) {
return (getOptConfig(opt).Name = name);
}
// Gibt den Namen einer Option zurueck // opt: Config und Value der Option // return Name der Option function getOptName(opt) {
return getOptConfig(opt).Name;
}
// Setzt den Wert einer Option // opt: Config und Value der Option // name: Zu setzender Wert der Option // return Gesetzter Wert function setOptValue(opt, value) {
return (opt !== undefined) ? (opt.Value = value) : undefined;
}
// Gibt den Wert einer Option zurueck // opt: Config und Value der Option // defValue: Default-Wert fuer den Fall, dass nichts gesetzt ist // return Gesetzter Wert function getOptValue(opt, defValue = undefined) {
return getValue((opt !== undefined) ? opt.Value : undefined, defValue);
}
// ==================== Ende Abschnitt fuer diverse Utilities ====================
// ==================== Abschnitt fuer das Benutzermenu ====================
// Zeigt den Eintrag im Menu einer Option // opt: Derzeitiger Wert der Option // menuOn: Text zum Setzen im Menu // funOn: Funktion zum Setzen // keyOn: Hotkey zum Setzen im Menu // menuOff: Text zum Ausschalten im Menu // funOff: Funktion zum Ausschalten // keyOff: Hotkey zum Ausschalten im Menu function registerMenuOption(opt, menuOn, funOn, keyOn, menuOff, funOff, keyOff) {
const __ON = (opt ? '*' : ""); const __OFF = (opt ? "" : '*');
console.log("OPTION " + __ON + menuOn + __ON + " / " + __OFF + menuOff + __OFF);
if (opt) {
GM_registerMenuCommand(menuOff, funOff, keyOff);
} else {
GM_registerMenuCommand(menuOn, funOn, keyOn);
}
}
// Zeigt den Eintrag im Menu einer Option mit Wahl des naechsten Wertes // opt: Derzeitiger Wert der Option // arr: Array-Liste mit den moeglichen Optionen // menu: Text zum Setzen im Menu ($ wird durch gesetzten Wert ersetzt) // fun: Funktion zum Setzen des naechsten Wertes // key: Hotkey zum Setzen des naechsten Wertes im Menu function registerNextMenuOption(opt, arr, menu, fun, key) {
const __MENU = menu.replace('$', opt);
let options = "OPTION " + __MENU;
for (let value of arr) {
if (value === opt) {
options += " / *" + value + '*';
} else {
options += " / " + value;
}
}
console.log(options);
GM_registerMenuCommand(__MENU, fun, key);
}
// Zeigt den Eintrag im Menu einer Option, falls nicht hidden // opt: Derzeitiger Wert der Option // menu: Text zum Setzen im Menu ($ wird durch gesetzten Wert ersetzt) // fun: Funktion zum Setzen des naechsten Wertes // key: Hotkey zum Setzen des naechsten Wertes im Menu // hidden: Angabe, ob Menupunkt nicht sichtbar sein soll (default: sichtbar) // serial: Serialization fuer komplexe Daten function registerDataOption(opt, menu, fun, key, hidden = false, serial = true) {
const __VALUE = ((serial && (opt !== undefined)) ? JSON.stringify(opt) : opt);
const __MENU = getValue(menu, "").replace('$', __VALUE);
const __OPTIONS = (hidden ? "HIDDEN " : "") + "OPTION " + __MENU +
getValue(__VALUE, "", " = " + __VALUE);
console.log(__OPTIONS);
if (! hidden) {
GM_registerMenuCommand(__MENU, fun, key);
}
}
// Zeigt den Eintrag im Menu einer Option // opt: Config und Value der Option function registerOption(opt) {
const __CONFIG = getOptConfig(opt);
if (! __CONFIG.HiddenMenu) {
switch (__CONFIG.Type) {
case __OPTTYPES.MC : registerNextMenuOption(getOptValue(opt), __CONFIG.Choice,
__CONFIG.Label, opt.Action, __CONFIG.Hotkey);
break;
case __OPTTYPES.SW : registerMenuOption(getOptValue(opt), __CONFIG.Label, opt.Action, __CONFIG.Hotkey,
__CONFIG.AltLabel, opt.Action, __CONFIG.AltHotkey);
break;
case __OPTTYPES.TF : registerMenuOption(getOptValue(opt), __CONFIG.Label, opt.Action, __CONFIG.Hotkey,
__CONFIG.AltLabel, opt.AltAction, __CONFIG.AltHotkey);
break;
case __OPTTYPES.SD : registerDataOption(getOptValue(opt), __CONFIG.Label, opt.Action, __CONFIG.Hotkey,
__CONFIG.HiddenMenu, __CONFIG.Serial);
break;
case __OPTTYPES.SI : registerDataOption(getOptValue(opt), __CONFIG.Label, opt.Action, __CONFIG.Hotkey,
__CONFIG.HiddenMenu, __CONFIG.Serial);
break;
default : break;
}
} else {
// Nur Anzeige im Log...
registerDataOption(getOptValue(opt), getOptName(opt), opt.Action, __CONFIG.Hotkey, __CONFIG.HiddenMenu, __CONFIG.Serial);
}
}
// ==================== Ende Abschnitt fuer das Benutzermenu ====================
// Initialisiert die gesetzten Option // config: Konfiguration der Option // return Initialwert der gesetzten Option function initOptValue(config) {
let value = config.Default; // Standard
switch (config.Type) {
case __OPTTYPES.MC : if ((value === undefined) && (config.Choice !== undefined)) {
value = config.Choice[0];
}
break;
case __OPTTYPES.SW : break;
case __OPTTYPES.TF : break;
case __OPTTYPES.SD : config.Serial = true;
break;
case __OPTTYPES.SI : break;
default : break;
}
if (config.Serial || config.Hidden) {
config.HiddenMenu = true;
}
return value;
}
// Initialisiert die Menue-Funktion einer Option // optAction: Typ der Funktion // item: Key der Option // optSet: Platz fuer die gesetzten Optionen (und Config) // return Funktion fuer die Option function initOptAction(optAction, item = undefined, optSet = undefined) {
var fun;
if (optAction !== undefined) {
const __CONFIG = getOptConfig(getOptByName(optSet, item));
const __RELOAD = ((__CONFIG !== undefined) ? __CONFIG.ActionReload : false);
switch (optAction) {
case __OPTACTION.SET : fun = function() {
return setOptByName(optSet, item, optSet.SetValue, __RELOAD);
};
break;
case __OPTACTION.NXT : fun = function() {
return setNextOptByName(optSet, item, optSet.SetValue, __RELOAD);
};
break;
case __OPTACTION.RST : fun = function() {
return resetOptions(optSet, __RELOAD);
};
break;
default : break;
}
}
return fun;
}
// Initialisiert die gesetzten Optionen // optConfig: Konfiguration der Optionen // optSet: Platz fuer die gesetzten Optionen // return Gefuelltes Objekt mit den gesetzten Optionen function initOptions(optConfig, optSet = undefined) {
var value;
if (optSet === undefined) {
optSet = { };
}
for (let opt in optConfig) {
const __CONFIG = optConfig[opt];
const __ALTACTION = getValue(__CONFIG.AltAction, __CONFIG.Action);
optSet[opt] = {
'Config' : __CONFIG,
'Value' : initOptValue(__CONFIG),
'SetValue' : undefined,
'Action' : initOptAction(__CONFIG.Action, opt, optSet),
'AltAction' : initOptAction(__ALTACTION, opt, optSet)
};
}
return optSet;
}
// Initialisiert die gesetzten Optionen und den Speicher und laedt die Optionen zum Start // optConfig: Konfiguration der Optionen // optSet: Platz fuer die gesetzten Optionen // return Gefuelltes Objekt mit den gesetzten Optionen function startOptions(optConfig, optSet = undefined) {
const __NORMAL = 'normal';
optSet = initOptions(optConfig, optSet);
// Memory Storage fuer vorherige Speicherung... const __OLDOPT = optSet.oldStorage; const __OLDSTORAGE = loadOption(getOpt(__OLDOPT), true); myOptMem = __OPTMEM[getValue(__OLDSTORAGE, __NORMAL)];
runStored(optSet); loadOptions(optSet);
// Memory Storage fuer naechste Speicherung...
const __STORAGE = getOptValue(optSet.storage, __NORMAL);
const __NEWSTORAGE = setOpt(__OLDOPT, __STORAGE, false);
if (! canUseStorage(myOptMem = __OPTMEM[getValue(__NEWSTORAGE, __NORMAL)])) {
const __INAKTIV = 'inaktiv';
if (__NEWSTORAGE !== __INAKTIV) {
setOpt(__OLDOPT, __INAKTIV, false);
myOptMem = __OPTMEM[__INAKTIV];
}
}
return optSet;
}
// Installiert die Visualisierung und Steuerung der Optionen // optSet: Platz fuer die gesetzten Optionen // optParams: Eventuell notwendige Parameter zur Initialisierung // 'hideMenu': Optionen werden zwar geladen und genutzt, tauchen aber nicht im Benutzermenu auf // 'menuAnchor': Startpunkt fuer das Optionsmenu auf der Seite // 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) // 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) // 'formWidth': Anzahl der Elemente pro Zeile // 'formBreak': Elementnummer des ersten Zeilenumbruchs function showOptions(optSet = undefined, optParams = { 'hideMenu' : false }) {
if (! optParams.hideMenu) {
buildMenu(optSet);
}
if ((optParams.menuAnchor !== undefined) && (myOptMem !== __OPTMEM.inaktiv)) {
buildForm(optParams.menuAnchor, optSet, optParams);
}
}
// Setzt eine Option auf einen vorgegebenen Wert // Fuer kontrollierte Auswahl des Values siehe setNextOpt() // opt: Config und vorheriger Value der Option // value: (Bei allen Typen) Zu setzender Wert // reload: Seite mit neuem Wert neu laden // return Gesetzter Wert function setOpt(opt, value, reload = false) {
return setOptValue(opt, setStored(getOptName(opt), value, reload, getOptConfig(opt).Serial));
}
// Ermittelt die naechste moegliche Option // opt: Config und Value der Option // value: Ggfs. zu setzender Wert // return Zu setzender Wert function getNextOpt(opt, value = undefined) {
const __CONFIG = getOptConfig(opt); const __VALUE = getOptValue(opt, value);
switch (__CONFIG.Type) {
case __OPTTYPES.MC : return getValue(value, getNextValue(__CONFIG.Choice, __VALUE));
case __OPTTYPES.SW : return getValue(value, ! __VALUE);
case __OPTTYPES.TF : return getValue(value, ! __VALUE);
case __OPTTYPES.SD : return getValue(value, __VALUE);
case __OPTTYPES.SI : break;
default : break;
}
return __VALUE;
}
// Setzt die naechste moegliche Option // opt: Config und Value der Option // value: Default fuer ggfs. zu setzenden Wert // reload: Seite mit neuem Wert neu laden // return Gesetzter Wert function setNextOpt(opt, value = undefined, reload = true) {
const __CONFIG = getOptConfig(opt);
return setOpt(opt, getNextOpt(opt, value), reload);
}
// Setzt eine Option auf einen vorgegebenen Wert (Version mit Key) // Fuer kontrollierte Auswahl des Values siehe setNextOptByName() // optSet: Platz fuer die gesetzten Optionen (und Config) // item: Key der Option // value: (Bei allen Typen) Zu setzender Wert // reload: Seite mit neuem Wert neu laden // return Gesetzter Wert function setOptByName(optSet, item, value, reload = false) {
const __OPT = getOptByName(optSet, item);
return setOpt(__OPT, value, reload);
}
// Ermittelt die naechste moegliche Option (Version mit Key) // opt: Config und Value der Option // optSet: Platz fuer die gesetzten Optionen (und Config) // item: Key der Option // value: Ggfs. zu setzender Wert // return Zu setzender Wert function getNextOptByName(optSet, item, value = undefined) {
const __OPT = getOptByName(optSet, item);
return getNextOpt(__OPT, value);
}
// Setzt die naechste moegliche Option (Version mit Key) // opt: Config und Value der Option // optSet: Platz fuer die gesetzten Optionen (und Config) // item: Key der Option // value: Ggfs. zu setzender Wert // reload: Seite mit neuem Wert neu laden // return Gesetzter Wert function setNextOptByName(optSet, item, value = undefined, reload = true) {
const __OPT = getOptByName(optSet, item);
return setNextOpt(__OPT, value, reload);
}
// Baut das Benutzermenu auf // optSet: Gesetzte Optionen function buildMenu(optSet) {
console.log("buildMenu()");
for (let opt in optSet) {
registerOption(optSet[opt]);
}
}
// Laedt eine (ueber Menu) gesetzte Option // opt: Zu ladende Option // force: Laedt auch Optionen mit 'AutoReset'-Attribut // return Gesetzter Wert der gelandenen Option function loadOption(opt, force = false) {
const __CONFIG = getOptConfig(opt);
if (! force && __CONFIG.AutoReset) {
return setOptValue(opt, initOptValue(__CONFIG));
} else if (__CONFIG.Serial) {
return setOptValue(opt, deserialize(getOptName(opt), getOptValue(opt)));
} else {
return setOptValue(opt, GM_getValue(getOptName(opt), getOptValue(opt)));
}
}
// Laedt die (ueber Menu) gesetzten Optionen // optSet: Set mit den Optionen // force: Laedt auch Optionen mit 'AutoReset'-Attribut // return Set mit den geladenen Optionen function loadOptions(optSet, force = false) {
for (let opt in optSet) {
loadOption(optSet[opt], force);
}
return optSet;
}
// Entfernt eine (ueber Menu) gesetzte Option (falls nicht 'Permanent') // opt: Gesetzte Option // force: Entfernt auch Optionen mit 'Permanent'-Attribut // reset: Setzt bei Erfolg auf Initialwert der Option function deleteOption(opt, force = false, reset = true) {
const __CONFIG = getOptConfig(opt);
if (force || ! __CONFIG.Permanent) {
GM_deleteValue(getOptName(opt));
if (reset) {
setOptValue(opt, initOptValue(__CONFIG));
}
}
}
// Entfernt die (ueber Menu) gesetzten Optionen (falls nicht 'Permanent') // optSet: Gesetzte Optionen // force: Entfernt auch Optionen mit 'Permanent'-Attribut // reset: Setzt bei Erfolg auf Initialwert der Option function deleteOptions(optSet, force = false, reset = true) {
for (let opt in optSet) {
deleteOption(optSet[opt], force, reset);
}
}
// Entfernt eine (ueber Menu) gesetzte Option // opt: Gesetzte Option // name: Neu zu setzender Name (Speicheradresse) // reload: Wert nachladen statt beizubehalten // force: Laedt auch Optionen mit 'AutoReset'-Attribut // return Umbenannte Option function renameOption(opt, name, reload = false, force = false) {
const __NAME = getOptName(opt);
if (__NAME !== name) {
deleteOption(opt, true, ! reload);
setOptName(opt, name);
if (reload) {
loadOption(opt, force);
}
}
return opt;
}
// Setzt die Optionen in optSet auf die "Werkseinstellungen" des Skripts // optSet: Gesetzte Optionen // reload: Seite mit "Werkseinstellungen" neu laden function resetOptions(optSet, reload = true) {
// Alle (nicht 'Permanent') gesetzten Optionen entfernen... deleteOptions(optSet, false, ! reload);
if (reload) {
// ... und Seite neu laden (mit "Werkseinstellungen")...
window.location.reload();
}
}
// ==================== Spezialisierter Abschnitt fuer Optionen ====================
// Gesetzte Optionen (wird von initOptions() angelegt und von loadOptions() gefuellt): const __OPTSET = { };
// Behandelt die Optionen und laedt das Benutzermenu // optConfig: Konfiguration der Optionen // optSet: Platz fuer die gesetzten Optionen // optParams: Eventuell notwendige Parameter zur Initialisierung // 'hideMenu': Optionen werden zwar geladen und genutzt, tauchen aber nicht im Benutzermenu auf // 'menuAnchor': Startpunkt fuer das Optionsmenu auf der Seite // 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) // 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) // 'formWidth': Anzahl der Elemente pro Zeile // 'formBreak': Elementnummer des ersten Zeilenumbruchs // return Gefuelltes Objekt mit den gesetzten Optionen function buildOptions(optConfig, optSet = undefined, optParams = { 'hideMenu' : false }) {
optSet = startOptions(optConfig, optSet);
showOptions(optSet, optParams);
return optSet;
}
// ==================== Abschnitt fuer diverse Utilities ====================
// Legt Input-Felder in einem Form-Konstrukt an, falls noetig // form: <form>...</form> // props: Map von name:value-Paaren // type: Typ der Input-Felder (Default: unsichtbare Daten) // return Ergaenztes Form-Konstrukt function addInputField(form, props, type = "hidden") {
for (let fieldName in props) {
let field = form[fieldName];
if (! field) {
field = document.createElement("input");
field.type = type;
field.name = fieldName;
form.appendChild(field);
}
field.value = props[fieldName];
}
return form;
}
// Legt unsichtbare Input-Daten in einem Form-Konstrukt an, falls noetig // form: <form>...</form> // props: Map von name:value-Paaren // return Ergaenztes Form-Konstrukt function addHiddenField(form, props) {
return addInputField(form, props, "hidden");
}
// Helferfunktion fuer alle Browser: Fuegt fuer ein Event eine Reaktion ein // obj: Betroffenes Objekt, z.B. ein Eingabeelement // type: Name des Events, z.B. "click" // callback: Funktion als Reaktion // capture: Event fuer Parent zuerst (true) oder Child (false als Default) // return false bei Misserfolg function addEvent(obj, type, callback, capture = false) {
if (obj.addEventListener) {
return obj.addEventListener(type, callback, capture);
} else if (obj.attachEvent) {
return obj.attachEvent("on" + type, callback);
} else {
console.log("Could not add " + type + " event:");
console.log(callback);
return false; }
}
// Helferfunktion fuer alle Browser: Entfernt eine Reaktion fuer ein Event // obj: Betroffenes Objekt, z.B. ein Eingabeelement // type: Name des Events, z.B. "click" // callback: Funktion als Reaktion // capture: Event fuer Parent zuerst (true) oder Child (false als Default) // return false bei Misserfolg function removeEvent(obj, type, callback, capture = false) {
if (obj.removeEventListener) {
return obj.removeEventListener(type, callback, capture);
} else if (obj.detachEvent) {
return obj.detachEvent("on" + type, callback);
} else {
console.log("Could not remove " + type + " event:");
console.log(callback);
return false; }
}
// Helferfunktion fuer alle Browser: Fuegt fuer ein Event eine Reaktion ein // id: ID des betroffenen Eingabeelements // type: Name des Events, z.B. "click" // callback: Funktion als Reaktion // capture: Event fuer Parent zuerst (true) oder Child (false als Default) // return false bei Misserfolg function addDocEvent(id, type, callback, capture = false) {
const __OBJ = document.getElementById(id);
return addEvent(__OBJ, type, callback, capture);
}
// Helferfunktion fuer alle Browser: Entfernt eine Reaktion fuer ein Event // id: ID des betroffenen Eingabeelements // type: Name des Events, z.B. "click" // callback: Funktion als Reaktion // capture: Event fuer Parent zuerst (true) oder Child (false als Default) // return false bei Misserfolg function removeDocEvent(id, type, callback, capture = false) {
const __OBJ = document.getElementById(id);
return removeEvent(__OBJ, type, callback, capture);
}
// Helferfunktion fuer die Ueberpruefung, ob ein Item sichtbar sein soll // item: Name des betroffenen Items // showList: Checkliste der sichtbaren Items (true fuer sichtbar) // hideList: Checkliste der unsichtbaren Items (true fuer unsichtbar) // return Angabe, ob das Item sichtbar sein soll function checkVisible(item, showList, hideList = undefined) {
let show = true;
if (showList !== undefined) {
show = (showList[item] === true); // gesetzt und true
}
if (hideList !== undefined) {
if (hideList[item] === true) { // gesetzt und true
show = false; // NICHT anzeigen
}
}
return show;
}
// Helferfunktion fuer die Ermittlung eines Elements der Seite (Default: Tabelle) // index: Laufende Nummer des Elements (0-based) // tag: Tag des Elements ("table") // doc: Dokument (document) function getTable(index, tag = "table", doc = document) {
const __TAGS = document.getElementsByTagName(tag); const __TABLE = __TAGS[index];
return __TABLE;
}
// Helferfunktion fuer die Ermittlung der Zeilen einer Tabelle // index: Laufende Nummer des Elements (0-based) // doc: Dokument (document) function getRows(index, doc = document) {
const __TABLE = getTable(index, "table", doc); const __ROWS = (__TABLE === undefined) ? undefined : __TABLE.rows;
return __ROWS;
}
// ==================== Abschnitt fuer Optionen auf der Seite ====================
// Liefert den Funktionsaufruf zur Option als String // opt: Auszufuehrende Option // isAlt: Angabe, ob AltAction statt Action gemeint ist // value: Ggfs. zu setzender Wert // serial: Serialization fuer String-Werte (Select, Textarea) // storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv // return String mit dem (reinen) Funktionsaufruf function getFormAction(opt, isAlt = false, value = undefined, serial = undefined, storage = undefined) {
const __STORAGE = getValue(storage, getValue(myOptMem, __OPTMEM.normal)); const __MEMORY = __STORAGE.Value; const __MEMSTR = __STORAGE.Display; const __RUNPREFIX = __STORAGE.Prefix;
if (__MEMORY !== undefined) {
const __RELOAD = "window.location.reload()";
const __SETITEM = function(item, val, quotes = true) {
return (__MEMSTR + ".setItem('" + __RUNPREFIX + item + "', " + (quotes ? "'" + val + "'" : val) + "),");
};
const __SETITEMS = function(cmd, key = undefined, val = undefined) {
return ('(' + __SETITEM('cmd', cmd) + ((key === undefined) ? "" :
__SETITEM('key', key) + __SETITEM('val', val, false)) + __RELOAD + ')');
};
const __CONFIG = getOptConfig(opt);
const __SERIAL = getValue(serial, getValue(__CONFIG.Serial, false));
const __THISVAL = ((__CONFIG.ValType === "String") ? "'\\x22' + this.value + '\\x22'" : "this.value");
const __TVALUE = getValue(__CONFIG.ValType, __THISVAL, "new " + __CONFIG.ValType + '(' + __THISVAL + ')');
const __VALSTR = ((value !== undefined) ? JSON.stringify(value) : __SERIAL ? "JSON.stringify(" + __TVALUE + ')' : __TVALUE);
const __ACTION = (isAlt ? getValue(__CONFIG.AltAction, __CONFIG.Action) : __CONFIG.Action);
if (__ACTION !== undefined) {
switch (__ACTION) {
case __OPTACTION.SET : //return "doActionSet('" + getOptName(opt) + "', " + getNextOpt(opt, __VALSTR) + ')';
return __SETITEMS('SET', getOptName(opt), __VALSTR);
case __OPTACTION.NXT : //return "doActionNxt('" + getOptName(opt) + "', " + getNextOpt(opt, __VALSTR) + ')';
return __SETITEMS('NXT', getOptName(opt), __VALSTR);
case __OPTACTION.RST : //return "doActionRst()";
return __SETITEMS('RST');
default : break;
}
}
}
return undefined;
}
// Liefert die Funktionsaufruf zur Option als String // opt: Auszufuehrende Option // isAlt: Angabe, ob AltAction statt Action gemeint ist // value: Ggfs. zu setzender Wert // type: Event-Typ fuer <input>, z.B. "click" fuer "onclick=" // serial: Serialization fuer String-Werte (Select, Textarea) // storage: __OPTMEM.normal = bis Browserende gespeichert (sessionStorage), __OPTMEM.unbegrenzt = unbegrenzt gespeichert (localStorage), __OPTMEM.inaktiv // return String mit dem (reinen) Funktionsaufruf function getFormActionEvent(opt, isAlt = false, value = undefined, type = "click", serial = undefined, storage = undefined) {
const __ACTION = getFormAction(opt, isAlt, value, serial, storage);
return getValue(__ACTION, "", ' on' + type + '="' + __ACTION + '"');
}
// Zeigt eine Option auf der Seite als Auswahlbox an // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionSelect(opt) {
const __CONFIG = getOptConfig(opt); const __NAME = getOptName(opt); const __VALUE = getOptValue(opt); const __ACTION = getFormActionEvent(opt, false, undefined, "change", undefined); const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label); const __LABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>'; let element = '<select name="' + __NAME + '" id="' + __NAME + '"' + __ACTION + '>';
for (let value of __CONFIG.Choice) {
element += '\n<option value="' + value + '"' +
((value === __VALUE) ? ' SELECTED' : "") +
'>' + value + '</option>';
}
element += '\n</select>';
return __LABEL.replace('$', element);
}
// Zeigt eine Option auf der Seite als Radiobutton an // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionRadio(opt) {
const __CONFIG = getOptConfig(opt);
const __NAME = getOptName(opt);
const __VALUE = getOptValue(opt, false);
const __ACTION = getFormActionEvent(opt, false, true, "click", false);
const __ALTACTION = getFormActionEvent(opt, true, false, "click", false);
const __ELEMENTON = '<input type="radio" name="' + __NAME +
'" id="' + __NAME + 'ON" value="1"' +
(__VALUE ? ' CHECKED' : __ACTION) +
' /><label for="' + __NAME + 'ON">' +
__CONFIG.Label + '</label>';
const __ELEMENTOFF = '<input type="radio" name="' + __NAME +
'" id="' + __NAME + 'OFF" value="0"' +
(__VALUE ? __ALTACTION : ' CHECKED') +
' /><label for="' + __NAME + 'OFF">' +
__CONFIG.AltLabel + '</label>';
return [ __ELEMENTON, __ELEMENTOFF ];
}
// Zeigt eine Option auf der Seite als Checkbox an // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionCheckbox(opt) {
const __CONFIG = getOptConfig(opt); const __NAME = getOptName(opt); const __VALUE = getOptValue(opt, false); const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, "click", false); const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
return '<input type="checkbox" name="' + __NAME +
'" id="' + __NAME + '" value="' + __VALUE + '"' +
(__VALUE ? ' CHECKED' : "") + __ACTION + ' /><label for="' +
__NAME + '">' + __FORMLABEL + '</label>';
}
// Zeigt eine Option auf der Seite als Daten-Textfeld an // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionTextarea(opt) {
const __CONFIG = getOptConfig(opt);
const __NAME = getOptName(opt);
const __VALUE = getOptValue(opt);
const __ACTION = getFormActionEvent(opt, false, undefined, "submit", undefined);
const __SUBMIT = getValue(__CONFIG.Submit, "");
const __ONSUBMIT = ((__SUBMIT.length > 0) ? ' onKeyDown="' + __SUBMIT + '"': "");
const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
const __ELEMENTLABEL = '<label for="' + __NAME + '">' + __FORMLABEL + '</label>';
const __ELEMENTTEXT = '<textarea name="' + __NAME + '" id="' + __NAME + '" cols="' + __CONFIG.Cols +
'" rows="' + __CONFIG.Rows + '"' + __ONSUBMIT + __ACTION + '>' +
JSON.stringify(__VALUE, __CONFIG.Replace, __CONFIG.Space) + '</textarea>';
return [ __ELEMENTLABEL, __ELEMENTTEXT ];
}
// Zeigt eine Option auf der Seite als Button an // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionButton(opt) {
const __CONFIG = getOptConfig(opt); const __NAME = getOptName(opt); const __VALUE = getOptValue(opt, false); const __ACTION = getFormActionEvent(opt, __VALUE, ! __VALUE, "click", false); const __BUTTONLABEL = (__VALUE ? __CONFIG.AltLabel : __CONFIG.Label); const __FORMLABEL = getValue(__CONFIG.FormLabel, __CONFIG.Label);
return '<label for="' + __NAME + '">' + __FORMLABEL +
'</label><input type="button" name="' + __NAME +
'" id="' + __NAME + '" value="' + __BUTTONLABEL + '"' +
__ACTION + '/>';
}
// Zeigt eine Option auf der Seite an (je nach Typ) // opt: Anzuzeigende Option // return String mit dem HTML-Code function getOptionElement(opt) {
const __CONFIG = getOptConfig(opt); const __TYPE = getValue(__CONFIG.FormType, __CONFIG.Type); let element = "";
if (! __CONFIG.Hidden) {
switch (__TYPE) {
case __OPTTYPES.MC : element = getOptionSelect(opt);
break;
case __OPTTYPES.SW : if (__CONFIG.FormLabel !== undefined) {
element = getOptionCheckbox(opt);
} else {
element = getOptionRadio(opt);
}
break;
case __OPTTYPES.TF : element = getOptionCheckbox(opt);
break;
case __OPTTYPES.SD : element = getOptionTextarea(opt);
break;
case __OPTTYPES.SI : element = getOptionButton(opt);
break;
default : break;
}
if (element.length === 2) {
element = '
' + element[1] + '
';
} }
return element;
}
// Baut das Benutzermenu auf der Seite auf // optSet: Gesetzte Optionen // optParams: Eventuell notwendige Parameter // 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) // 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) // 'formWidth': Anzahl der Elemente pro Zeile // 'formBreak': Elementnummer des ersten Zeilenumbruchs // return String mit dem HTML-Code function getForm(optSet, optParams = { }) {
const __FORM = '<form id="options" method="POST">
<tbody>'; const __FORMEND = '</tbody></form>';
const __FORMWIDTH = getValue(optParams.formWidth, 3);
const __FORMBREAK = getValue(optParams.formBreak, __FORMWIDTH);
const __SHOWFORM = getOptValue(optSet.showForm, true) ? optParams.showForm : { 'showForm' : true };
let form = __FORM;
let count = 0; // Bisher angezeigte Optionen
let column = 0; // Spalte der letzten Option (1-basierend)
for (let opt in optSet) {
if (checkVisible(opt, __SHOWFORM, optParams.hideForm)) {
const __ELEMENT = getOptionElement(optSet[opt]);
const __TDOPT = (__ELEMENT.indexOf('|') < 0) ? ' colspan="2"' : "";
if (__ELEMENT.length > 0) {
if (++count > __FORMBREAK) {
if (++column > __FORMWIDTH) {
column = 1;
}
}
if (column === 1) {
form += ''; } form += '\n<td' + __TDOPT + '>' + __ELEMENT.replace('|', '') + '';
}
}
}
form += '\n' + __FORMEND;
return form;
}
// Fuegt das Script in die Seite ein // optSet: Gesetzte Optionen // optParams: Eventuell notwendige Parameter // 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) // 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) // return String mit dem HTML-Code fuer das Script function getScript(optSet, optParams = { }) {
//const __SCRIPT = '<script type="text/javascript">function activateMenu() { console.log("TADAAA!"); }</script>';
//const __SCRIPT = '<script type="text/javascript">\n\tfunction doActionNxt(key, value) { alert("SET " + key + " = " + value); }\n\tfunction doActionNxt(key, value) { alert("SET " + key + " = " + value); }\n\tfunction doActionRst(key, value) { alert("RESET"); }\n</script>';
//const __FORM = '<form method="POST"><input type="button" id="showOpts" name="showOpts" value="Optionen anzeigen" onclick="activateMenu()" /></form>';
const __SCRIPT = "";
//window.eval('function activateMenu() { console.log("TADAAA!"); }');
return __SCRIPT;
}
// Zeigt das Optionsmenu auf der Seite an (im Gegensatz zum Benutzermenu) // anchor: Element, das als Anker fuer die Anzeige dient // optSet: Gesetzte Optionen // optParams: Eventuell notwendige Parameter // 'showForm': Checkliste der auf der Seite sichtbaren Optionen (true fuer sichtbar) // 'hideForm': Checkliste der auf der Seite unsichtbaren Optionen (true fuer unsichtbar) // 'formWidth': Anzahl der Elemente pro Zeile // 'formBreak': Elementnummer des ersten Zeilenumbruchs function buildForm(anchor, optSet, optParams = { }) {
console.log("buildForm()");
const __FORM = getForm(optSet, optParams); const __SCRIPT = getScript(optSet, optParams);
addForm(anchor, __FORM, __SCRIPT);
}
// Informationen zu hinzugefuegten Forms const __FORMS = { };
// Zeigt das Optionsmenu auf der Seite an (im Gegensatz zum Benutzermenu) // anchor: Element, das als Anker fuer die Anzeige dient // form: HTML-Form des Optionsmenu (hinten angefuegt) // script: Script mit Reaktionen function addForm(anchor, form = "", script = "") {
const __OLDFORM = __FORMS[anchor];
const __REST = (__OLDFORM === undefined) ? anchor.innerHTML :
anchor.innerHTML.substring(0, anchor.innerHTML.length - __OLDFORM.Script.length - __OLDFORM.Form.length);
__FORMS[anchor] = { 'Script' : script, 'Form' : form };
anchor.innerHTML = __REST + script + form;
}
// ==================== Ende Abschnitt fuer Optionen ====================
// ==================== Hauptprogramm ====================
// Verarbeitet eine Ergebnis-Ansicht function procErgebnisse() {
buildOptions(__OPTCONFIG, __OPTSET, {
'menuAnchor' : getTable(0, "div"),
'formWidth' : 2
});
// Aktiviere Checkbox "Ergebnisse anzeigen" je nach Einstellung der Option getTable(0, "input").checked = getOptValue(__OPTSET.showErgs);
}
procErgebnisse();
console.log("SCRIPT END");
// *** EOF ***