GM_config_lz-string

Refactor GM_config, this version uses lz-string to access data for a Library script

Version vom 02.10.2018. Aktuellste Version

Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greatest.deepsurf.us/scripts/372760/633458/GM_config_lz-string.js

// ==UserScript==
// @namespace     http://tampermonkey.net/
// @exclude       *

// ==UserLibrary==
// @name          GM_config_lz-string
// @description   Refactor GM_config, this version uses lz-string to access data for a Library script
// @author        avan
// @license       MIT
// @version       0.4

// ==/UserScript==

// ==/UserLibrary==

GM_configStruct.prototype.read = function (store) {
	var rval, cKey, dValue;
	try {
		cKey = LZString.compressToUTF16(store || this.id);
		dValue = LZString.decompressFromUTF16(this.getValue(cKey, '{}'));
		rval = this.parser(dValue);
	} catch(e) {
		this.log("GM_config failed to read saved settings!");
		rval = {};
	}
	return rval;
};

GM_configStruct.prototype.write = function (store, obj) {
	if (!obj) {
		var values = {},
			forgotten = {},
			fields = this.fields;

		for (var id in fields) {
			var field = fields[id];
			var value = field.toValue();

			if (field.save) {
				if (value !== null) {
					values[id] = value;
					field.value = value;
				} else
					values[id] = field.value;
			} else
				forgotten[id] = value;
		}
	}
	try {
		var cKey = LZString.compressToUTF16(store || this.id),
			cValue = LZString.compressToUTF16(this.stringify(obj || values));
		this.setValue(cKey, cValue);
	} catch(e) {
		this.log("GM_config failed to save settings!");
	}

	return forgotten;
};
GM_configField.prototype.toNode = function() {
	var field = this.settings,
		value = this.value,
		options = field.options,
		type = field.type,
		className = field.class,
		style = field.style,
		id = this.id,
		configId = this.configId,
		labelPos = field.labelPos,
		create = this.create;
	function addLabel(pos, labelEl, parentNode, beforeEl) {
		if (!beforeEl) beforeEl = parentNode.firstChild;
		switch (pos) {
			case 'right':
			case 'below':
				if (pos == 'below')
					parentNode.appendChild(create('br', {}));
				parentNode.appendChild(labelEl);
				break;
			default:
				if (pos == 'above')
					parentNode.insertBefore(create('br', {}), beforeEl);
				parentNode.insertBefore(labelEl, beforeEl);
		}
	}
	var retNode = create('div', {
		className: 'config_var',
		id: configId + '_' + id + '_var',
		title: field.title || '',
		
	}),
		firstProp;
	// Retrieve the first prop
	for (var i in field) {
		firstProp = i;
		break;
	}
	var label = field.label && type != "button" ?
		create('label', {
			id: configId + '_' + id + '_field_label',
			for: configId + '_field_' + id,
			className: 'field_label'
		}, field.label) : null;
	var props = {className: className, style: style};
	switch (type) {
		case 'textarea':
			props.innerHTML = value;
			props.id = configId + '_field_' + id;
			props.className = (props.className ? props.className + ' ' : '') + 'block';
			props.cols = (field.cols ? field.cols : 20);
			props.rows = (field.rows ? field.rows : 2);
			retNode.appendChild((this.node = create('textarea', props)));
			break;
		case 'radio':
			props.id = configId + '_field_' + id;
			var wrap = create('div', props);
			this.node = wrap;
			for (var i = 0, len = options.length; i < len; ++i) {
				var radLabel = create('label', {
					className: 'radio_label'
				}, options[i]);
				var rad = wrap.appendChild(create('input', {
					value: options[i],
					type: 'radio',
					name: id,
					checked: options[i] == value
				}));
				var radLabelPos = labelPos &&
					(labelPos == 'left' || labelPos == 'right') ?
					labelPos : firstProp == 'options' ? 'left' : 'right';
				addLabel(radLabelPos, radLabel, wrap, rad);
			}
			retNode.appendChild(wrap);
			break;
		case 'select':
			props.id: configId + '_field_' + id;
			var wrap = create('select', props);
			this.node = wrap;
			for (var i = 0, len = options.length; i < len; ++i) {
				var option = options[i];
				wrap.appendChild(create('option', {
					value: option,
					selected: option == value
				}, option));
			}
			retNode.appendChild(wrap);
			break;
		default: // fields using input elements
			props.id = configId + '_field_' + id;
			props.type = type;
			props.value = type == 'button' ? field.label : value;
			switch (type) {
				case 'checkbox':
					props.checked = value;
					break;
				case 'button':
					props.size = field.size ? field.size : 25;
					if (field.script) field.click = field.script;
					if (field.click) props.onclick = field.click;
					break;
				case 'hidden':
					break;
				case 'password':
					props.size = field.size ? field.size : 25;
					break;
				default:
					// type = text, int, or float
					props.type = 'text';
					props.size = field.size ? field.size : 25;
			}
			retNode.appendChild((this.node = create('input', props)));
	}
	if (label) {
		// If the label is passed first, insert it before the field
		// else insert it after
		if (!labelPos)
			labelPos = firstProp == "label" || type == "radio" ?
				"left" : "right";
		addLabel(labelPos, label, retNode);
	}
	return retNode;
};