Configuration Dialog

A enhanced configuration dialog for Userscripts.

Versión del día 30/04/2018. Echa un vistazo a la versión más reciente.

Este script no debería instalarse directamente. Es una biblioteca que utilizan otros scripts mediante la meta-directiva de inclusión // @require https://update.greasyfork.org/scripts/45343/272542/Configuration%20Dialog.js

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

/*
/////////////////////////////////////////////////////
#                                                   #
#          Script made by Marius Adam               #
#                ©DevForce 2018                     #
#               Code Version 0.2                    #
#                                                   #
/////////////////////////////////////////////////////
*/

var configurationWindow = {
	maximized: false,
	minimized: false,

	changed: false,

    data: undefined,
	window_id: "window",

	values: {},
	
	get : function(id){
		return this.values[id];
	},
	
	getElseSet : function(id, def, ifNone){
		var val = this.get(id);
		if(val == undefined){
			if(def == undefined){
				val = ifNone;
				this.set(id, ifNone);
			}else{
				val = def;
				this.set(id, def);
			}
		}
		return val;
	},
	
	set : function(id, value){
		this.values[id] = value;
	},
	
	save : function(){
		GM_setValue(this.window_id, JSON.stringify(this.values));
		console.debug("Saved to #" + this.window_id, this.values);
	},
	
	load : function(){
		var loaded = GM_getValue(this.window_id);
		if(loaded == undefined || loaded.length < 2) loaded = "{}";
		this.values = JSON.parse(loaded);
		console.debug("Loaded Values: ", this.values);
	},
	
	updateChanged : function() {
		this.changed = ($('[style="border: 2px solid rgb(255, 244, 0);"]').length + $('[style="outline: rgb(255, 244, 0) solid 3px;"]').length) > 0;
		
		$('#' + this.window_id).find('#saveButton').prop("disabled", ! this.changed);
		$('#' + this.window_id).find('#revertButton').prop("disabled", ! this.changed);
	},
	
	maximize : function() {
		$('#' + this.window_id).find('#content').show();
		$('#' + this.window_id).find('#footer').show();
		$('#' + this.window_id).find('#theme_dropdown').show();
		$("#window_minimize").show();
		$('#' + this.window_id).width("calc(100% - 20px)");
		$('#' + this.window_id).height("calc(100% - 20px)");
		$('#' + this.window_id).css("top", "7px");
		$('#' + this.window_id).css("left", "7px");
		$('#' + this.window_id).css("min-height", "");

		this.maximized = true;
		this.minimized = false;
	},

	minimize : function(){
		$('#' + this.window_id).find('#content').hide();
		$('#' + this.window_id).find('#footer').hide();
		$('#' + this.window_id).find('#theme_dropdown').hide();
		$("#window_minimize").hide();
		$('#' + this.window_id).width("50%");
		$('#' + this.window_id).height("25px");
		$('#' + this.window_id).css("top", "calc(100% - 30px)");
		$('#' + this.window_id).css("left", "25%");
		$('#' + this.window_id).css("min-height", "30px");

		this.minimized = true;
	},

	normalize : function(){
		$('#' + this.window_id).find('#content').show();
		$('#' + this.window_id).find('#footer').show();
		$('#' + this.window_id).find('#theme_dropdown').show();
		$("#window_minimize").show();
		$('#' + this.window_id).width("");
		$('#' + this.window_id).height("");
		$('#' + this.window_id).css("top", "");
		$('#' + this.window_id).css("left", "");
		$('#' + this.window_id).css("min-height", "");

		this.maximized = false;
		this.minimized = false;
	},

	clearSelection : function(){
		if (window.getSelection) {
			if (window.getSelection().empty) {  // Chrome
				window.getSelection().empty();
			} else if (window.getSelection().removeAllRanges) {  // Firefox
				window.getSelection().removeAllRanges();
			}
		} else if (document.selection) {  // IE
			document.selection.empty();
		}
	},

	makeDragable : function(move, dragbox, useBorder) {
		if(dragbox == undefined) dragbox = move;
		if(useBorder == undefined) useBorder = true;

		var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0, dragged = false;

		dragbox.onmousedown = dragMouseDown;

		function dragMouseDown(e) {
			e = e || window.event;
			if(configurationWindow.minimized){
				document.onmouseup = null;
				document.onmousemove = null;
				return;
			}
			// get the mouse cursor position at startup:
			pos3 = e.clientX;
			pos4 = e.clientY;
			document.onmouseup = closeDragElement;
			// call a function whenever the cursor moves:
			document.onmousemove = elementDrag;
		}

		function elementDrag(e) {
			e = e || window.event;
			
			// calculate the new cursor position:
			pos1 = pos3 - e.clientX;
			pos2 = pos4 - e.clientY;
			pos3 = e.clientX;
			pos4 = e.clientY;
			
			// set the element's new position:
			var new_top = move.offsetTop - pos2;
			var new_left = move.offsetLeft - pos1;
			
			if(configurationWindow.maximized){
				configurationWindow.normalize();
				new_top = e.clientY;
				new_left = e.clientX;
			}
			
			if(useBorder){
				var max_width = $(window).width() - $(move).width();
				var max_height = $(window).height() - $(move).height();
				if(new_top < 0) new_top = 0;
				else if(new_top > max_height) new_top = max_height; 
				if(new_left < 0) new_left = 0;
				else if(new_left > max_width) new_left = max_width;
			}
			
			move.style.left = new_left + "px";
			move.style.top = new_top + "px";
			dragged = true;
			
			configurationWindow.clearSelection();
		}

		function closeDragElement() {
			/* stop moving when mouse button is released:*/
			if(useBorder && dragged){
				if(move.style.top.indexOf("%") == -1 && move.style.top.replace("px", "") < 2)
					configurationWindow.maximize();
			}
			document.onmouseup = null;
			document.onmousemove = null;
		}
	},

	isArray : function(what) {
		return Object.prototype.toString.call(what) === '[object Array]';
	},

	isObject : function(what) {
		return Object.prototype.toString.call(what) === '[object Object]';
	},

	join : function(labelFirst, label, element){
		return (labelFirst ? label + " " + element : element + " " + label);
	},

	replaceAll : function(target, search, replacement) {
		return target.replace(new RegExp(search, 'g'), replacement);
	},

	revertChanges : function(){
		$('#' + this.window_id).find("#content").find("input[type=text], input[type=password], input[type=number], input[type=color]").each(function(){
			$(this).val($(this).attr("value"));
			$(this).css("border", "");
		});

		$('#' + this.window_id).find("#content").find("select").each(function(){
			this.value = $(this).find("option[selected]").val();
			$(this).css("border", "");
		});

		$('#' + this.window_id).find("#content").find('input[type=checkbox]:not(.toggle)').each(function() {
			this.checked = $(this).attr("default") == "true";
			$(this).css("outline", "");
		});

		this.updateChanged();
	},

	saveChanges : function(){
		$('#' + this.window_id).find("#content").find("input[type=text], input[type=password], input[type=number], input[type=color]").each(function(){
			configurationWindow.set(this.id, this.value);
			$(this).attr("value", this.value);
			$(this).css("border", "");
		});

		$('#' + this.window_id).find("#content").find("select").each(function(){
			configurationWindow.set(this.id, this.value);

			var main_val = this.value;

			$(this).find("option[selected]").removeAttr("selected");
			$(this).find("option").filter(function() {
				return this.innerHTML == main_val;
			}).attr("selected", "selected");

			this.value = main_val;

			$(this).css("border", "");
		});

		$('#' + this.window_id).find("#content").find('input[type=checkbox]:not(.toggle)').each(function() {
			configurationWindow.set(this.id, this.checked);
			$(this).attr("default", this.checked);
			$(this).css("outline", "");
		});

		this.updateChanged();
		this.save();
	},

    ResetSettings : function(){
        if(this.isArray(this.data.content)){
			for(i = 0; i < this.data.content.length; i++){
				if(this.isObject(this.data.content[i])){
					var object = this.data.content[i];
                    object.default = (object.default == undefined ? "" : object.default);
                    
                    var elem = $('#' + this.window_id).find("#content").find("#" + object.id);
					
					var type = elem.attr("type");
					if(type == undefined && elem.is("select")) type = "select"; 
						
                    switch(type){
						case "text":
						case "number":
						case "password":
						case "select":
							$(elem).val(object.default);
							break;
						case "checkbox":
							$(elem).prop("checked", object.default);
							break;
						default: break;
					}
					$(elem).change();
                }
            }
        }
        this.updateChanged();
    },

	close : function(){
		if(this.changed){
			if(!confirm(this.data.confirm_close)){
				return false;
			}
		}
		$('#' + this.window_id).attr("style", "display: none;");
		return true;
	},
	
    open : function(data){
        $('#' + this.window_id).attr("style", "");
    },

	create : function(data){
		//var data = JSON.parse(content);

        this.data = data;
		
        if(this.window_id != undefined)
            $('#' + this.window_id).remove();

		$('#window_style').remove();
		$('#font-awesome').remove();

		if(data.id == undefined) data.id = "window";
		this.window_id = data.id;

		this.load();
	
		$('head').append('<link id="font-awesome" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">');

		if (data.theme == undefined) data.theme = "mac";
		if (!(data.theme == "mac" || data.theme == "win10" || data.theme == "winXP")) data.theme = "mac";
		
		var saved_theme = GM_getValue("config_theme");
		if(data.theme_selector == undefined || data.theme_selector == true || data.theme_selector == "true"){
			data.theme_selector = true;
			if(saved_theme != undefined) data.theme = saved_theme;
		}else{
			data.theme_selector = false;
		}
		
		if(data.width == undefined) data.width = 50;
		if(data.height == undefined) data.height = 50;
		
		var section_color = "#c9c9c9";
		var subsection_color = "#f1f1f1";
		
		var style = "<style id='window_style'>";
		if(data.theme == "mac"){
			style += `
				#` + this.window_id + ` > #top > .btn {
					height: 16px;
					width: 16px;
					background-color: #bbb;
					border-radius: 50%;
					float: right;
					margin-right: 10px;
					display: inline-block;
					font-size: 10px;
					text-align: center;
					color: white;
					cursor: pointer;
					//font-weight: bold;
				}

				#` + this.window_id + ` > #top > .title {
					margin: auto;
					font-size: 16px;
					font-weight: bold;
					cursor: move;
				}

				#` + this.window_id + ` {
					border: 3px solid #f1f1f1;
					border-top-left-radius: 3px;
					border-top-right-radius: 3px;
					height: ` + data.height + `%;
					width: ` + data.width + `%;
					top: ` + ((100 - data.height) / 2) + `%;
					left: ` + ((100 - data.width) / 2) + `%;
					position: fixed;
					z-index: 11000;
					background: white;
					min-width: 250px;
					min-height: 250px;
					resize: both;
					overflow: auto;
					line-height: unset;
					overflow-y: hidden;`
				+ (data.font != undefined ?
					 (data.font.size != undefined ? "font-size: " + data.font.size + ";" : "")  +
					 (data.font.family != undefined ? "font-family: " + data.font.family + ";" : "")
				   : "") +
				`}

				#` + this.window_id + ` > #top {
					padding: 10px;
					//height: 20px;
					background: #f1f1f1;
					border-top-left-radius: 4px;
					border-top-right-radius: 4px;
					position: absolute;
					width: calc(100% - 20px);
				}
			`;
		}else if(data.theme == "win10"){
			section_color = "#1f9cff";
			subsection_color = "#9dd4ff";
			style += `
				#` + this.window_id + ` > #top > .btn {
					height: 22px;
					width: 30px;
					float: right;
					margin-right: 5px;
					display: inline-block;
					font-size: 16px;
					text-align: center;
					color: white;
					cursor: pointer;
					color: black;
					padding: 2px;
				}
				
				#` + this.window_id + ` > #top > #window_minimize:hover, #` + this.window_id + ` > #top > #window_maximize:hover {
					background-color: #ddd;
				}
				
				#` + this.window_id + ` > #top > #window_close:hover {
					background-color: red;
				}

				#` + this.window_id + ` > #top > .title {
					margin: auto;
					font-size: 16px;
					font-weight: bold;
					cursor: move;
					padding: 10px;
				}

				#` + this.window_id + ` {
					border: 3px solid #1f9cff;
					height: ` + data.height + `%;
					width: ` + data.width + `%;
					top: ` + ((100 - data.height) / 2) + `%;
					left: ` + ((100 - data.width) / 2) + `%;
					position: fixed;
					z-index: 11000;
					background: white;
					min-width: 250px;
					min-height: 250px;
					resize: both;
					overflow: auto;
					line-height: unset;
					overflow-y: hidden;`
				+ (data.font != undefined ?
					 (data.font.size != undefined ? "font-size: " + data.font.size + ";" : "")  +
					 (data.font.family != undefined ? "font-family: " + data.font.family + ";" : "")
				   : "") +
				`}

				#` + this.window_id + ` > #top {
					//padding: 10px;
					//height: 20px;
					background: #1f9cff;
					position: absolute;
					width: 100%;
				}
			`;
		}else if(data.theme == "winXP"){
			section_color = "#226ce7";
			subsection_color = "#4094ff";
			style += `
				#` + this.window_id + ` > #top > .btn {
					height: 20px;
					width: 20px;
					float: right;
					margin-right: 5px;
					margin-top: 5px;
					display: inline-block;
					font-size: 16px;
					text-align: center;
					color: white;
					cursor: pointer;
					color: white;
					border-radius: 2px;
					padding: 2px;
					border: 1px solid white;
					background: linear-gradient(135deg, #7EAED6 0%, #1B72FF 50%, #1655BE 100%);
				}
				
				#` + this.window_id + ` > #top > #window_minimize:hover, #` + this.window_id + ` > #top > #window_maximize:hover {
					background: linear-gradient(135deg, #6a93b5 0%, #1862da 50%, #124499 100%);
				}
				
				#` + this.window_id + ` > #top > #window_close {
					background: linear-gradient(135deg, #F1A689 0%, #C0442A 50%, #C2311E 100%);
				}
				
				#` + this.window_id + ` > #top > #window_close:hover {
					background: linear-gradient(135deg, #c3846c 0%, #a43923 50%, #982415 100%);
				}

				#` + this.window_id + ` > #top > .title {
					margin: auto;
					font-size: 16px;
					font-weight: bold;
					cursor: move;
					padding: 10px;
					color: white;
				}

				#` + this.window_id + ` {
					border-left: 3px solid #0056e4;
					border-right: 3px solid #0056e4;
					border-bottom: 3px solid #0056e4;
					height: ` + data.height + `%;
					width: ` + data.width + `%;
					top: ` + ((100 - data.height) / 2) + `%;
					left: ` + ((100 - data.width) / 2) + `%;
					position: fixed;
					z-index: 11000;
					background: white;
					min-width: 250px;
					min-height: 250px;
					border-radius: 8px;
					resize: both;
					overflow: auto;
					line-height: unset;
					overflow-y: hidden;`
				+ (data.font != undefined ?
					 (data.font.size != undefined ? "font-size: " + data.font.size + ";" : "")  +
					 (data.font.family != undefined ? "font-family: " + data.font.family + ";" : "")
				   : "") +
				`}

				#` + this.window_id + ` > #top {
					//padding: 10px;
					//height: 20px;
					border-radius: 5px 5px 0px 0px;
					background: linear-gradient(to bottom, #4094ff 0%, #0056e4 13%, #0056e4 71%, #16428b 100%);
					position: absolute;
					width: 100%;
				}
			`;
		}
		
		style += `
			#` + this.window_id + ` > #footer {
				text-align: right;
				margin: 0px 0px 4px -20px;
				height: 40px;
				border-top-left-radius: 4px;
				border-top-right-radius: 4px;
				position: absolute;
				width: 100%;
				bottom: 0;
			}

			#` + this.window_id + ` > #footer > button {
				background-color: #f1f1f1;
				border: none;
				color: black;
				padding: 12px 40px;
				font-size: 14px;
				cursor: pointer;
				margin-left: 5px;
			}

			#` + this.window_id + ` > #footer > button:hover {
				background-color: RoyalBlue;
				color: white;
			}
			
			#` + this.window_id + ` > #footer > button:disabled {
				background-color: darkgrey;
				color: white;
			}
			
			#` + this.window_id + ` > #content {
				padding: 10px;
				margin-top: 40px;
				overflow-y: scroll;
				height: calc(100% - 75px);
				overflow-wrap: break-word;
			}

			#` + this.window_id + ` > #content > input,#` + this.window_id + ` > #content > select {`
				 + (data.font != undefined ?
				 (data.font.size != undefined ? "font-size: " + data.font.size + ";" : "")  +
				 (data.font.family != undefined ? "font-family: " + data.font.family + ";" : "")
			   : "") +
			`}

			#` + this.window_id + ` > #content > br {
				display: block;
				margin-top: 4px;
				content: " ";
			}

			#` + this.window_id + ` > #theme_dropdown {
				float: left;
				bottom: 5px;
				position: absolute;
				left: 5px;
				border: none;
				-webkit-appearance: none;
				-moz-appearance: none;
				appearance: none;
				color: gray;
			}
			
			#` + this.window_id + ` > #theme_dropdown > option {
				color: black;
			}
			
			.no-margin {
				margin: 0px;
			}
			
			.wrap-collapsible {
				margin-bottom: 1.2rem 0;
			}

			.toggle {
				display: none;
			}

			.lbl-toggle {
				display: block;
				cursor: pointer;
				
				transition: all 0.25s ease-out;
			}
			
			.lbl-toggle h2, .lbl-toggle h4 {
				display: inline;
			}

			.lbl-toggle:hover {
				color: white;
			}

			.lbl-toggle::before {
				content: ' ';
				display: inline-block;

				border-top: 5px solid transparent;
				border-bottom: 5px solid transparent;
				border-left: 5px solid currentColor;
				vertical-align: middle;
				margin-right: .7rem;
				transform: translateY(-2px);

				transition: transform .2s ease-out;
			}

			.toggle:checked + .lbl-toggle::before {
				transform: rotate(90deg) translateX(-3px);
			}

			.collapsible-content {
				max-height: 0px;
				overflow: hidden;
				transition: max-height .25s ease-in-out;
			}

			.toggle:checked + .lbl-toggle + .collapsible-content {
				max-height: 350px;
			}

			.collapsible-content .content-inner {
				//background: rgba(161, 161, 161, 0.2);
				//border: 1px solid black;
			}
		`;
		
		style += "<style>";
		
		$('head').append(style);
		
		if(data.theme_section_color == undefined || data.theme_section_color == false){
			section_color = "#c9c9c9";
			subsection_color = "#f1f1f1";
		}
		
		var content = "";

		if(this.isArray(data.content)){
			var section_collapsible = false;
			var subsection_collapsible = false;
			var collapsible_id = 1;
			
			for(i = 0; i < data.content.length; i++){
				if(this.isObject(data.content[i])){
					var label_first = undefined;
					Object.keys(data.content[i]).forEach(function(key){
						if(label_first != undefined) return;

						if(key == "label") label_first = true;
						else if(key == "type") label_first = false;
					});

					var label = this.replaceAll(data.content[i].label, "  ", "&nbsp;&nbsp;");

					var object = data.content[i];

					if(object.style != undefined) object.style = " style='" + object.style + "'";
					else object.style = "";

					if(object.require != undefined) object.style += " require='" + object.require + "'";
					
					switch(object.type){
						case "p":
							content += "<p class='no-margin'" + object.style + ">" + label  + "</p>";
							break;
						case "h1":
							content += "<h1 class='no-margin'" + object.style + ">" + label + "</h1>";
							break;
						case "h2":
							content += "<h2 class='no-margin'" + object.style + ">" + label + "</h2>";
							break;
						case "h3":
							content += "<h3 class='no-margin'" + object.style + ">" + label + "</h3>";
							break;
						case "h4":
							content += "<h4 class='no-margin'" + object.style + ">" + label + "</h4>";
							break;
						case "section":
							if(object.align == undefined) object.align = "center";
							if(object.background == undefined) object.background = section_color;
							
							if(subsection_collapsible){
								content += "</div></div></div>";
								subsection_collapsible = false;
							}
							
							if(section_collapsible){
								content += "</div></div></div>";
								section_collapsible = false;
							}
							
							if(object.collapsible != undefined && object.collapsible){
								content += "<div class='wrap-collapsible'><input id='collapsible" + collapsible_id + "' class='toggle' type='checkbox' " + (object.collapsed != undefined && object.collapsed == false ? "checked" : "") + "><label style='margin: 5px 0px 0px 0px; background: " + object.background + "; text-align: " + object.align + ";' for='collapsible" + collapsible_id + "' class='lbl-toggle'><h2>" + label + "</h2></label><div class='collapsible-content'><div class='content-inner'>";
								section_collapsible = true;
								collapsible_id++;
							}else{
								content += "<div width='100%' style='margin: 5px 0px; background: " + object.background + "; text-align: " + object.align + ";'><h2 class='no-margin'>" + label + "</h2></div>";
							}
							break;
						case "subsection":
							if(object.align == undefined) object.align = "center";
							if(object.background == undefined) object.background = subsection_color;
							
							if(subsection_collapsible){
								content += "</div></div></div>";
								subsection_collapsible = false;
							}
							
							if(object.collapsible != undefined && object.collapsible){
								content += "<div class='wrap-collapsible'><input id='collapsible" + collapsible_id + "' class='toggle' type='checkbox' " + (object.collapsed != undefined && object.collapsed == false ? "checked" : "") + "><label style='margin: 5px 0px 0px 0px; background: " + object.background + "; text-align: " + object.align + ";' for='collapsible" + collapsible_id + "' class='lbl-toggle'><h4>" + label + "</h4></label><div class='collapsible-content'><div class='content-inner'>";
								subsection_collapsible = true;
								collapsible_id++;
							}else{
								content += "<div width='100%' style='margin: 5px 0px; background: " + object.background + "; text-align: " + object.align + ";'><h4 class='no-margin'>" + label + "</h4></div>";
							}
							break;
						case "text":
							var value = this.getElseSet(object.id, object.default, "");
							
							content += this.join(label_first, label, "<input id='" + object.id + "'" + object.style + " type='text' value='" + value + "' />");

							content += "<br>";
							break;
						case "password":
							var value = this.getElseSet(object.id, object.default, "");
							
							content += this.join(label_first, label, "<input id='" + object.id + "'" + object.style + " type='password' value='" + value + "' />");

							content += "<br>";
							break;
						case "checkbox":
							var value = this.getElseSet(object.id, object.default, false);
							
							if(value == "true" || value == true) value = true;
							else value = false;

							label = "<label for='" + object.id + "'>" + label + "</label>";
							
							content += this.join(label_first, label, "<input id='" + object.id + "'" + object.style + " default='" + value + "' type='checkbox' " + (value ? "checked" : "") + "/>");

							content += "<br>";
							break;
						case "select":
							var value = this.getElseSet(object.id, object.default, "");

							var select = " <select" + object.style + " id='" + object.id + "'>";
							object.options.forEach(function(opt){
								if(opt == value){
									select += "<option selected>" + opt + "</option>";
								}else{
									select += "<option>" + opt + "</option>";
								}
							});
							select += "</select> ";

							content += this.join(label_first, label, select);

							content += "<br>";
							break;
						case "numeric":
							var value = this.getElseSet(object.id, object.default, 0);
							
							var element = "<input id='" + object.id + "'" + object.style + " type='number' value='" + value + "'";
							if(object.min != undefined) element += " min='" + object.min + "'";
							if(object.max != undefined) element += " max='" + object.max + "'";
							element += " />";
							
							content += this.join(label_first, label, element);

							content += "<br>";
							break;
						case "color":
							var value = this.getElseSet(object.id, object.default, "#FFFFFF");

							content += this.join(label_first, label, "<input id='" + object.id + "'" + object.style + " type='color' value='" + value + "' />");

							content += "<br>";
							break;
						default: break;
					}
				}else{
					content += "<p>" + data.content[i] + "</p>";
				}
			}
			
			if(subsection_collapsible){
				content += "</div></div></div>";
				section_collapsible = false;
			}
			
			if(section_collapsible){
				content += "</div></div></div>";
				section_collapsible = false;
			}
		}else{
			content = data.content;
		}
		content += "<br style='height: 25px;' />";
		
		var buttons = "";

        if(data.completeresetbutton == undefined || data.completeresetbutton == true || data.completeresetbutton == "true"){
            buttons += "<button id='completeResetButton'><i class='fa fa-trash'></i></button>";
        }

		if(data.revertbutton == undefined || data.revertbutton == true ||  data.revertbutton == "true"){
			buttons += "<button id='revertButton'><i class='fa fa-undo'></i></button>";
		}

		if(data.savebutton == undefined || data.savebutton == true ||  data.savebutton == "true"){
			buttons += "<button id='saveButton'><i class='fa fa-save'></i></button>";
		}

		var topbuttons = "";
		if(data.top == undefined || data.top.close == undefined || data.top.close == "true"){
			if(data.theme == "mac")		topbuttons += '<span id="window_close" class="btn" style="background:#ED594A; margin-right: 20px;"><i class="fa fa-times" style="vertical-align: sub;"></i></span>';
			else if(data.theme == "win10") topbuttons += '<span id="window_close" class="btn" style="margin-right: 0px;"><i class="fa fa-times"></i></span>';
			else if(data.theme == "winXP") topbuttons += '<span id="window_close" class="btn"><i class="fa fa-times"></i></span>';
		}
		
		if(data.top == undefined || data.top.maximize == undefined || data.top.maximize == "true"){
			if(data.theme == "mac")		topbuttons += '<span id="window_maximize" class="btn" style="background:#FDD800;"><i class="fa fa-window-maximize" style="vertical-align: sub;"></i></span>';
			else if(data.theme == "win10" || data.theme == "winXP") topbuttons += '<span id="window_maximize" class="btn"><i class="fa fa-window-maximize"></i></span>';
		}
		
		if(data.top == undefined || data.top.minimize == undefined || data.top.minimize == "true"){
			if(data.theme == "mac")		topbuttons += '<span id="window_minimize" class="btn" style="background:#5AC05A;"><i class="fa fa-window-minimize" style="vertical-align: sub;"></i></span>';
			else if(data.theme == "win10" || data.theme == "winXP") topbuttons += '<span id="window_minimize" class="btn"><i class="fa fa-window-minimize"></i></span>';
		}
		

		$('body').append(`
			<div id="` + this.window_id + `" style='display: none;' class="window">
				<div id="top">
					` + topbuttons +
					`<p class="title">` + data.title + `</p>
				</div>

				<div id="content">
					` + content + `
				</div>

				<div id="footer">
					` + buttons + `
				</div>
				` +
				(data.theme_selector ? `<select id="theme_dropdown" value="Theme">
					<option value="std" style="display: none;">Theme</option>
					<option value="mac">Mac</option>
					<option value="win10">Windows 10</option>
					<option value="winXP">Windows XP</option>
				</select>` : "") + `
			</div>
		`);

		this.makeDragable($('#' + this.window_id)[0], $('#' + this.window_id).find("#top")[0], true);

        var confirm_close = "Unsaved changes. Discard changes?";
        var confirm_revert = "Reset all changes?";
        var confirm_reset = "Bring settings back to factory settings?";
        if(data.confirm_close != undefined) confirm_close = data.confirm_close;
        if(data.confirm_revert != undefined) confirm_revert = data.confirm_revert;
        if(data.confirm_reset != undefined) confirm_reset = data.confirm_reset;

		$('#' + this.window_id).find('#revertButton').click(function(){
            if(confirm(confirm_revert)) configurationWindow.revertChanges();
		});
		
		$('#' + this.window_id).find('#saveButton').click(function(){
			configurationWindow.saveChanges();
            $('#' + configurationWindow.window_id).find('#saveButton').css("background", "lime");
            setTimeout(function(){
                $('#' + configurationWindow.window_id).find('#saveButton').css("background", "");
            }, 1000);
		});

        $('#' + this.window_id).find('#completeResetButton').click(function(){
			if(confirm(confirm_reset)) configurationWindow.ResetSettings();
		});

        $('#' + this.window_id).find('#window_close').click(function(){
            configurationWindow.close();
		});

		//================ WINDOW RESIZE BUTTONS ===================//
		$('#' + this.window_id).find('#window_maximize').click(function(){
			if(configurationWindow.maximized && !configurationWindow.minimized)
				configurationWindow.normalize();
			else
				configurationWindow.maximize();
		});

		$('#' + this.window_id).find('#window_minimize').click(function(){
			configurationWindow.minimize();
		});

		$('#' + this.window_id).find("#top").dblclick(function(){
			if(configurationWindow.minimized){
				if(configurationWindow.maximized)
					configurationWindow.maximize();
				else
					configurationWindow.normalize();
			}else{
				if(configurationWindow.maximized)
					configurationWindow.normalize();
				else
					configurationWindow.maximize();
			}
			configurationWindow.clearSelection();
		});

		//==================== THEME SELECTOR =======================//
		$('#' + this.window_id).find("#theme_dropdown").change(function(){
			if(! configurationWindow.close()) return;
			GM_setValue("config_theme", this.value);
			configurationWindow.create(configurationWindow.data);
			configurationWindow.open();
		});
		

		//==================== FIELD CHANGE LISTENER =====================//
		$('#' + this.window_id).find("#content").find("input[type=text], input[type=number], input[type=password], input[type=color]").change(function(){
			if($(this).attr("value") != $(this).val())
				$(this).css("border", "#fff400 solid 2px");
			else
				$(this).css("border", "");

			configurationWindow.updateChanged();
		});
		 
		$('#' + this.window_id).find("#content").find("input[type=number]").change(function(){
			if($(this).attr("min") != undefined && $(this).val() < parseFloat($(this).attr("min")))
				$(this).val($(this).attr("min"));
			else if($(this).attr("max") != undefined && $(this).val() > parseFloat($(this).attr("max"))){
				$(this).val($(this).attr("max"));
			}
			
			configurationWindow.updateChanged();
		});

		

		$('#' + this.window_id).find("#content").find("select").change(function(){
			if(this.value != $(this).find("option[selected]").val())
				$(this).css("border", "#fff400 solid 2px");
			else
				$(this).css("border", "");

			configurationWindow.updateChanged();
		});

		$('#' + this.window_id).find("#content").find('input[type=checkbox]:not(.toggle)').change(function() {
			if(this.checked != ($(this).attr("default") == "true")){
				$(this).css("outline", "#fff400 solid 3px");
			}else{
				$(this).css("outline", "");
			}
			
			$('[require="' + this.id + '"]').prop("disabled", !this.checked);
			
			configurationWindow.updateChanged();
		});
		
		$('#' + this.window_id).find("#content").find('input[type=checkbox]:not(.toggle)').trigger("change");
		
		$(document).keyup(function(e) {
			if (e.keyCode == 27) {
				configurationWindow.close();
			}
		});
		
		this.updateChanged();
	}
};