WME Keep My Layers

Resets WME layers to your preferred state plus other fancy stuff.

当前为 2016-01-02 提交的版本,查看 最新版本

// ==UserScript==
// @name 			WME Keep My Layers
// @description 	Resets WME layers to your preferred state plus other fancy stuff.
// @namespace       https://greasyfork.org/users/11629-TheLastTaterTot
// @version 		0.2.1
// @include         https://editor-beta.waze.com/*editor/*
// @include         https://www.waze.com/*editor/*
// @exclude         https://www.waze.com/user/*editor/*
// @author			TheLastTaterTot
// @grant           none
// @grant           GM_getValue
// @grant           GM_setValue
// @grant           GM_deleteValue
// @run-at          document-start
// ==/UserScript==

(function() {
	document.onreadystatechange = function(e) {
		if (document.readyState === 'interactive') {
			$("html").css("visibility", "hidden");
			var pl_host = false,
				pl_path = false;
			// Check for beta-editor
			if (undefined !== GM_getValue("WMEKML_Beta") || GM_getValue("WMEKML_Lang") ===
				true) {
				if (GM_getValue("WMEKML_Beta") === true && //if set to beta-editor
					location.host.indexOf('editor-b') !== 0) { //if PL is not editor-beta.waze.com
					pl_host = 'https://editor-beta.waze.com';
				} else if (GM_getValue("WMEKML_Beta") === false && //if set to production editor
					location.host.indexOf('www') !== 0) { //if PL is not www.waze.com
					pl_host = 'http://www.waze.com';
				}

				// Check for language
				if (GM_getValue("WMEKML_Lang") === true) { //if set to filter out language
					if (location.pathname != '/editor/') {
						pl_path = '/editor/';
					}
				}

				switch (true) {
					case (!pl_host && !pl_path):
						break;
					default:
						if (!pl_host) pl_host = location.origin;
						if (!pl_path) pl_path = location.pathname;

						location.replace(pl_host + pl_path + location.href.substring(location.href
							.indexOf('?'), location.href.length));
				}
			}
		}
	}


	// -------------------------------------------------------------------------
	//Waze.map.layers.forEach(function(a){console.debug(a["name"] + ': ' + a["visibility"])})
	function GetWazeMapLayersFromSwitcher(L) { // get OL layers that show up under the WME Layer switcher panel
		var l, numTotalLayers = L.length,
			layerName, layerUniqName,
			layerSwitcherPanel = {
				accelerator: {},
				uniqueName: {}
			};

		for (l = numTotalLayers; l--;) {
			layerName = L[l].accelerator;
			layerUniqName = L[l].uniqueName;
			if (layerName !== undefined) { // we check the accelerator name bc it is a marker with high specificity and selectivity of whether the layer appears in the layer switcher menu
				if (layerUniqName !== undefined) { // however, we actually want the uniqueName since that matches the name saved in localStorage by WME
					//L[layerName] = Waze.map.layers[l].name;  //not sure if I want this, so saving it here just in case...
					layerSwitcherPanel.uniqueName[layerUniqName] = l; //name the property by its uniqueName and save its index for Waze.map.layers
					layerSwitcherPanel.accelerator[layerName] = l;
				} else {
					console.log('WMEKML: Note - No uniqueName found for "' + L[l].name + '"');
					layerSwitcherPanel.accelerator[layerName] = l;
				}
			}
		}
		return layerSwitcherPanel
	}
	// -----------------------------------------------------------------------------

	function ResetLayersToSaved(exclusion) {
		if (typeof KML_myLayers !== "undefined") {
			var L = Waze.map.layers,
				j, lname,
				layerSwitcherPanel = GetWazeMapLayersFromSwitcher(L),
				accelNamesObj = layerSwitcherPanel.accelerator,
				visibilityFromWazeLocalStorage, visibleLayersInSwitcherPanel;

			// Fix saved WME layers settings in localStorage
			visibilityFromWazeLocalStorage = JSON.parse(localStorage.layerVisibility);
			KML_myLayers.visibilityFromWazeLocalStorage_orig =
				JSON.parse(JSON.stringify(visibilityFromWazeLocalStorage));
			$.extend(true, visibilityFromWazeLocalStorage, KML_myLayers.visibilityFromWazeLocalStorage);
			localStorage.layerVisibility = JSON.stringify(
				visibilityFromWazeLocalStorage); // Save it

			// Now fix layer visibility on the map...
			visibleLayersInSwitcherPanel = KML_myLayers.visibleLayersInSwitcherPanel;
			if (exclusion) visibleLayersInSwitcherPanel[exclusion] = true;

			accelNames = Object.keys(accelNamesObj);
			j = accelNames.length;
			while (j--) {
				lname = accelNames[j];
				L[accelNamesObj[lname]].setVisibility(!!visibleLayersInSwitcherPanel[lname]);
			}

			KML_myLayers.reset = true;
			KML_myLayers.uniqueName = layerSwitcherPanel.uniqueName;

			EnableUndoLayersReset();
			return true
		} else {
			return false
		}
	}

	// -------------------------------------------------------------------------
	/* ["toggleLiveUsers", "toggleRouteCheckerScript", "toggleJunctionAngleInfo",
	"toggleWMEClosestSegment", "toggleRoadClosures", "toggleEditableAreas",
	"toggleUpdateRequests", "toggleMapProblems", "toggleSpeedcameras", "toggleJunctionboxes",
	"togglePlaceupdates", "togglePlaces", "toggleAreaManagers", "toggleGPSpoints",
	"toggleRoads", "toggleCities", "toggleSatelliteImagery"] */
	function CheckForNeededLayers(permalink) {
		switch (true) {
			case permalink.indexOf('&mapUp') !== -1:
				return "toggleUpdateRequests"
			case permalink.indexOf('&ven') !== -1:
				return "togglePlaces"
			case permalink.indexOf('&mapPr') !== -1:
				return "toggleMapProblems"
			case permalink.indexOf('&bigJ') !== -1:
				return "toggleJunctionboxes"
			case permalink.indexOf('&cam') !== -1:
				return "toggleSpeedcameras"
			default:
				return false
		}
	}
	// -------------------------------------------------------------------------
	// TODO: Remove KML_myLayers from global later
	// TODO: function for temporarily reverting to the layers provided by PL
	// -------------------------------------------------------------------------
	function SaveMyVisibleLayers() {
		var L = Waze.map.layers,
			j, lname,
			layerSwitcherPanel = GetWazeMapLayersFromSwitcher(L),
			layerNames = Object.keys(layerSwitcherPanel.accelerator),
			numLayers = layerNames.length,
			visibleLayersInSwitcherPanel = {}, // visibleLayersSavedByWaze = [],
			visibilityFromWazeLocalStorage;

		// Get names of visible menu layers
		for (j = numLayers; j--;) {
			lname = layerNames[j];
			if (L[layerSwitcherPanel.accelerator[lname]].getVisibility()) {
				visibleLayersInSwitcherPanel[lname] = true;
			}
		}

		// Get names of visible layers saved by WME in localStorage
		visibilityFromWazeLocalStorage = JSON.parse(localStorage.layerVisibility);
		/*
		layerNames = Object.keys(visibilityFromWazeLocalStorage);
		numLayers = layerNames.length;
		for (j = numLayers; j--;) {
			lname = layerNames[j];
			if (visibilityFromWazeLocalStorage[lname]) {
				visibleLayersSavedByWaze.push(lname);
			}
		}
		*/
		// Save to localStorage
		KML_myLayers = {
			visibleLayersInSwitcherPanel: visibleLayersInSwitcherPanel, //visibleLayersSavedByWaze: visibleLayersSavedByWaze,
			visibilityFromWazeLocalStorage: visibilityFromWazeLocalStorage
		};
		localStorage.WME_KeepMyLayers = JSON.stringify(KML_myLayers);
		$("#layer-switcher-list").after(
			'<div id="KMLpopup" style="font-weight: bold; color: #DD3300; position: absolute; display: block; bottom: 30px; right: 14px">Saved &lt;</div>'
		);
		setTimeout(function() {
			$("#KMLpopup").remove()
		}, 650)

	}


	// -----------------------------------------------------------------------------

	function LookForSavedLayers() {
		switch (true) {
			case typeof KML_myLayers !== "undefined":
				if (KML_myLayers.visibleLayersInSwitcherPanel !== undefined) {
					console.log(
						'WMEKML: Replaced KML_myLayers in memory with saved version from disk.'
					)
					KML_myLayers = JSON.parse(localStorage.WME_KeepMyLayers);
					return true
				} else {
					return false
				}
			case localStorage.WME_KeepMyLayers !== undefined:
				//console.log('WMEKML: Found some saved settings to load!')
				KML_myLayers = JSON.parse(localStorage.WME_KeepMyLayers);

				if (KML_myLayers.visibleLayersInSwitcherPanel !== undefined) {
					/* Remove this in a later version.... */
					if (KML_myLayers.visibleLayersInSwitcherPanel.constructor === Array) {
						vlay = {};
						KML_myLayers.visibleLayersInSwitcherPanel.map(function(item) {
							return vlay[item] = true
						})
						KML_myLayers.visibleLayersInSwitcherPanel = vlay;
						localStorage.WME_KeepMyLayers = JSON.stringify(KML_myLayers);
					}
					return true
				} else {
					return false
				}
			default:
				/* TODO: Call to popup of instructions for saving default layers set will maybe go here */
				return false
		}
	}

	function UserResetOfLayersToSaved() {
		if (LookForSavedLayers()) {
			ResetLayersToSaved(false)
		} else {
			console.log('WMEKML: Nothing to reset.')
			return false
		}
	}

	function CheckForOtherStuff() {
		// ['&x', '&b', '&l', '&1', '&5', '&2']; //disable, beta, lang, city, am, roads
		//console.log('WMEKML: Checking other layer options...')
		if (localStorage.WME_KML_Settings.indexOf('&1') !== -1) {
			Waze.map.layers[1].setOpacity(1);
			console.log('WMEKML: Opacity of Cities layer increased.')
		} else {
			Waze.map.layers[1].setOpacity(0.5);
			console.log('WMEKML: Opacity of Cities layer at default.')
		}

		if (localStorage.WME_KML_Settings.indexOf('&5') !== -1) {
			Waze.map.layers[5].setOpacity(0.5);
			console.log('WMEKML: Opacity of AM layer decreased.')
		} else {
			Waze.map.layers[5].setOpacity(1);
			console.log('WMEKML: Opacity of AM layer at default.')
		}

		if (localStorage.WME_KML_Settings.indexOf('&2') !== -1) {
			Waze.map.layers[2].setOpacity(0.72);
			console.log('WMEKML: Opacity of Roads layer decreased.')
		} else {
			Waze.map.layers[2].setOpacity(1);
			console.log('WMEKML: Opacity of Roads layer at default.')
		}

	}

	// Beta Editor ToggleButton
	function BetaToggle() {
		if ($("#user-details").length !== 0) {
			var togStatus = !!GM_getValue("WMEKML_Beta");

			$("#kml-css-container").append(
				'.kml-toggle-container { position: absolute; right: 10px; top: 10px; } ' +
				'.kml-toggle { position: relative; width: 40px; ' +
				'-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } ' +
				'.kml-toggle-checkbox { display: none; } ' +
				'.kml-toggle-label { display: block;  overflow: hidden; cursor: pointer;  border: 2px solid #CDCDCD; border-radius: 20px; } ' +
				'.kml-toggle-inner { display: block; width: 200%; margin-left: -100%; transition: margin 0.2s ease-in 0s; } ' +
				'.kml-toggle-inner:before, .kml-toggle-inner:after {  ' +
				'display: block; float: left; width: 50%; height: 20px;  ' +
				'padding: 0; line-height: 20px; font-size: 10px; box-sizing: border-box; } ' +
				'.kml-toggle-inner:before { content: ""; padding-left: 5px; background-color: #FC6C70; } ' +
				'.kml-toggle-inner:after { content: ""; padding-right: 5px; background-color: #CDCDCD; } ' +
				'.kml-toggle-switch { display: block; width: 24px; margin: 0px;  ' +
				'position: absolute; top: 0; bottom: 0; right: 16px; background: #FFFFFF; ' +
				'border: 2px solid #CDCDCD; border-radius: 20px; transition: all 0.2s ease-in 0s; } ' +
				'.kml-toggle-checkbox:checked + .kml-toggle-label .kml-toggle-inner { margin-left: 0; } ' +
				'.kml-toggle-checkbox:checked + .kml-toggle-label .kml-toggle-switch { right: 0px; }'
			);

			(togStatus) ? togStatus = 'checked': togStatus = '';
		
		
			$("#user-details").prepend(
				'<div class="kml-toggle-container"><div class="kml-toggle">' +
				'<input type="checkbox" name="kml-toggle" class="kml-toggle-checkbox" id="cbKMLtoggle"' +
				togStatus + '>' +
				'<label class="kml-toggle-label" for="cbKMLtoggle">' +
				'<span class="kml-toggle-inner"></span>' +
				'<span class="kml-toggle-switch"></span></label></div></div>');

			$("#cbKMLtoggle").click(function() {
				GM_setValue("WMEKML_Beta", this.checked)
			})
		} else {
			setTimeout(BetaToggle,500);
		}
	}

	function KMLSettingsPanel() {

		// get dimensions of waze map area
		var l,
			panelHeight = 350,
			panelWidth = 530;

		$("#kml-css-container").append(
			'div.kml-panel-blackout { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; ' +
			'background: rgba(0,0,0,0.5); z-index: 2000; } ' +
			'.kml-panel { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); ' +
			'width: ' + panelWidth + 'px; height: ' + panelHeight + 'px; ' +
			'padding: 10px; margin: 0; ' +
			'overflow-y: auto; overflow-x: auto; background-color: white; ' +
			'border: 1px solid #858585; border-radius: 10px; box-shadow: 0px 5px 20px #555555; } ' +
			'.kml-panel h2 { margin-top:10px; font-size: 20pt; font-weight: bold; text-align: left; color: #C0C0C0 } ' +
			'div.kml-panel-section {display: block; font-size: 12pt; text-align: left } ' +
			'.kml-panel-hr { position: block; border: 0; height: 0; border-top: 1px solid rgba(0, 0, 0, 0.1); border-bottom: 1px solid rgba(255, 255, 255, 0.3); } ' +
			'.kml-panel-btn {margin: 0px 5px; padding: 0px 15px; display: inline-block; height: 32px; } ' +
			'div.kml-panel-btn {display: block; position: relative; padding: 0; width: 480px; margin: auto; vertical-align: middle; height: 40px; }'
		);

		// setup checkbox list for UI
		var kmlOptions = [
			'Show WME Beta Editor toggle in the left side-panel', //[0]
			'Remove language specifications from clicked permalinks', //[1]
			'Make Cities layer polygons darker', //[2] layer 1 - 1city
			'Make Area Managers layer more translucent', //[3] layer 5 - 5am
			'Make Road layer slightly see-through to see satellite image', //[4] layer 2 - 2roads
			'Disable automatic checking for Keep My Layers'
		]; //[5] xx

		var settingsUI =
			'<div id="KMLsettings" class="kml-panel-blackout"><div class="kml-panel">' +
			'<i id="iKMLsettings" class="icon-cog icon-4x pull-left fa fa-cog fa-4x fa-pull-left"></i>' +
			'<h2>Keep My Layers Settings</h2>' +
			'<hr class="kml-panel-hr">' +
			'<div class="kml-panel-section">';

		//TODO: Clean the following code up....
		var checkedTog = Array(kmlOptions.length),
			allStr = ['&b', '&l', '&1', '&5', '&2', '&x']; //beta, lang, city, am, roads, disable
		(localStorage.WME_KML_Settings === undefined) ? checkStr = ':': checkStr =
			localStorage.WME_KML_Settings;

		if (GM_getValue("WMEKML_Beta") !== undefined && localStorage.WME_KML_Settings
			.indexOf("&b") === -1) {
			localStorage.WME_KML_Settings += "&b";
			checkStr += "&b";
		}
		if (GM_getValue("WMEKML_Lang") !== undefined && localStorage.WME_KML_Settings
			.indexOf("&l") === -1) {
			localStorage.WME_KML_Settings += "&l"
			checkStr += "&l";
		}

		for (l = 0; l < kmlOptions.length; l++) {
			(checkStr.indexOf(allStr[l]) !== -1) ? checkedTog[l] = ' checked':
				checkedTog[l] = ' ';
			settingsUI += '<div class="controls-container">' +
				'<input type="checkbox" id="cbKML_' + l +
				'" class="btn btn-default"' + checkedTog[l] + '></input>' +
				'<label for="cbKML_' + l + '">' + kmlOptions[l] + '</label></div>';
		}
		settingsUI += '</div>' +
			'<div style="font-size: 10; margin-left: 35px; margin-top: 0px; margin-bottom: 0px;">Does not include the first two settings above</div>' +
			'<hr class="kml-panel-hr">' +
			'<div class="kml-panel-btn"><div style="display: inline-block; margin-left: 0px;">' +
			'<button id="btnKMLsave" class="btn btn-default kml-panel-btn">Save</button>' +
			'<button id="btnKMLcancel" class="btn btn-default kml-panel-btn">Cancel</button></div>' +
			'<div id="KMLnote" style="color: #81B5C6; position: absolute; right: 5px; display: inline-block; text-align: right; width: 300px; line-height: 15px; height: 40px; vertical-align: middle"></div></div></div></div>';
		$("#map").append(settingsUI)

		if (!LookForSavedLayers()) {
			$("#KMLnote").append(
				'<i style="font-size:10px">Note: You have not saved a default set of layers. Select your Layers preferences under the Layers menu and click</i><div style="color: #48758C; margin-left: 4px; display:inline-block" class="icon-save fa-save"></div>'
			)
		}

		$("#btnKMLsave").click(function() {
			if (document.getElementById("cbKML_0").checked) {
				GM_setValue("WMEKML_Beta", !!(location.host.indexOf('editor-b') + 1));
				BetaToggle();
			} else {
				GM_deleteValue("WMEKML_Beta");
			}

			if (document.getElementById("cbKML_1").checked) {
				GM_setValue("WMEKML_Lang", true);
			} else {
				GM_deleteValue("WMEKML_Lang")
			}

			var storeStr = ':'
			if ($("#cbKML_5")[0].checked) storeStr += '&x' //disable KML
			if ($("#cbKML_0")[0].checked) storeStr += '&b' //beta
			if ($("#cbKML_1")[0].checked) storeStr += '&l' //lang
			if ($("#cbKML_2")[0].checked) storeStr += '&1' //city
			if ($("#cbKML_3")[0].checked) storeStr += '&5' //am
			if ($("#cbKML_4")[0].checked) storeStr += '&2' //roads

			localStorage.WME_KML_Settings = storeStr;

			CheckForOtherStuff();
			$("#KMLsettings").remove();
		});
		$("#btnKMLcancel").click(function() {
			$("#KMLsettings").remove()
		});
	}

	function EnableUndoLayersReset() {
		// the following blocks of code needs cleaning up....
		if (typeof KML_myLayers !== "undefined" && KML_myLayers.reset !== undefined &&
			KML_myLayers.reset === true) {
			var wazeLayerNames = Object.keys(KML_myLayers.visibilityFromWazeLocalStorage_orig),
				l = wazeLayerNames.length,
				toggledLayers = [],
				t = 0;

			while (l--) {
				if (KML_myLayers.visibilityFromWazeLocalStorage_orig[wazeLayerNames[l]] !==
					KML_myLayers.visibilityFromWazeLocalStorage[wazeLayerNames[l]]) {
					toggledLayers[t++] = wazeLayerNames[l];
				}
			}

			var nToggled = toggledLayers.length;
			if (nToggled !== 0) {
				console.log('WMEKML: Layers were reset to your saved settings.')
				$("#iKMLtempUndo").wrap(
					'<a href="javascript:void(0)" class="kml-icn"></a>');
				$("#iKMLtempUndo").toggleClass("kml-icn-off, kml-icn-on");

				/*  //document.getElementsByClassName("toggler")
				$("#iKMLtempUndo").hover(function() {
						for (t = nToggled; t--;) {
							Waze.map.layers[KML_myLayers.uniqueName[toggledLayers[t]]].visibility =
								true;
						}
					},
					function() {
						for (t = nToggled; t--;) {
							Waze.map.layers[KML_myLayers.uniqueName[toggledLayers[t]]].visibility =
								false;
						}
					});
				*/
				$("#iKMLtempUndo").click(function() {
					this.toggleClass("kml-icn-on")
					this.toggle(function() {
							for (t = nToggled; t--;) {
								Waze.map.layers[KML_myLayers.uniqueName[toggledLayers[t]]].setVisibility(
									true);
							}
						},
						function() {
							for (t = nToggled; t--;) {
								Waze.map.layers[KML_myLayers.uniqueName[toggledLayers[t]]].setVisibility(
									false);
							}
						});
				});
			}
		}
	}

	function InitKMLButtons() {
		if ( $("#layer-switcher-list").length !== 0 ) {
			var el = document.createElement("style");
			el.type = "text/css";
			el.id = "kml-css-container"
			document.body.appendChild(el);

			// CSS for WMEKML
			$("#kml-css-container").append(
				'div.kml-icn { position: absolute; display: inline-block; vertical-align: center; bottom: 0px; right: 0px; padding: 0; margin: 0px 10px 10px 0px; }' +
				'.kml-icn-save { position: relative; display: block; bottom: 45px; right: 0px }' +
				'.kml-icn-btn { position: relative; display: inline-block; padding-left: 4px; padding-right: 4px; }' + //right: 30px; top: 10px; 'width: 12px; height: 12px;
				'.kml-icn:active, .kml-icn:focus, .kml-icn:hover, .kml-icn.active { text-decoration: none; background-image: none; outline: 0; -webkit-box-shadow: none; box-shadow: none; }' +
				'.kml-icn-on { color: #B1D4DF; !important }' + //
				'.kml-icn-off, .kml-icn-off:hover, .kml-icn-off:focus { color: #B1D4DF; !important }' +
				'span.kml-icn-btn { padding: 0; margin: 0px 10px 10px 0px; }'
			);

			// Add save layers icon to Layers switcher dropdown panel
			$("#layer-switcher-list").after('<div class="kml-icn">' +
				'<a href="javascript:void(0)" class="kml-icn"><div id="iKMLsaveLayers" class="icon-save fa fa-save kml-icn-btn reload-button" data-toggle="tooltip" title="Save selected layers"></div></a>' +
				'<a href="javascript:void(0)" class="kml-icn"><div id="iKMLsettings" class="icon-cog fa fa-cog kml-icn-btn reload-button" data-toggle="tooltip" title="KML Settings"></div></a>' +
				'<a href="javascript:void(0)" class="kml-icn"><div id="iKMLresetLayers" class="icon-magic fa fa-magic kml-icn-btn reload-button" data-toggle="tooltip" title="Apply Keep My Layers"></div></a>' +
				'<div id="iKMLtempUndo" class="icon-eye-open fa fa-eye kml-icn-btn reload-button kml-icn-off" data-toggle="tooltip" title="Reshow removed layers (buggy)"></div>' +
				'</div>');
			// style="color: #B1D4DF !important"

			// Setup event listeners
			$("#iKMLsaveLayers").click(SaveMyVisibleLayers);
			$("#iKMLsettings").click(KMLSettingsPanel);
			$("#iKMLresetLayers").click(UserResetOfLayersToSaved);
			$("[data-toggle=tooltip]").tooltip({
				placement: 'bottom'
			});


			if (GM_getValue("WMEKML_Beta") !== undefined) BetaToggle();
		} else {
			setTimeout(InitKMLButtons,500);
		}
	}

	function AutoChecks() {
		//		if (permalink.indexOf('&lay') !== -1) {
		if (localStorage.WME_KML_Settings === undefined) {
			localStorage.WME_KML_Settings = ':';
		}

		if (localStorage.WME_KML_Settings.indexOf('&x') !== -1) { // user has set WMEKML to be disabled
			console.log("WMEKML: Autochecking of Keep My Layers have been disabled.")
			return false
		} else {
			if (LookForSavedLayers()) {
				ResetLayersToSaved(CheckForNeededLayers(location.href)); //functions returns t/f... do something with this later (TODO)
			}
			CheckForOtherStuff();
		}
	}


	// =============================================================================
	var initCount = 0;

	function Init_WMEKML() {
		if (initCount < 20) {
			initCount++;
			try {
				if ("undefined" !== typeof Waze && Waze.map && Waze.map.layers) {
					console.log('WMEKML: Starting...')
					AutoChecks();
					InitKMLButtons();
				} else {
					setTimeout(Init_WMEKML, 500);
				}
			} catch (err) {
				console.warn(
					'WMEKML: Initialization of WME Keep My Layers has been unsuccessful. Trying again... ' +
					err);
				setTimeout(Init_WMEKML, 3000);
			}
		} else {
			console.error(
				'WMEKML: WME Keep My Layers failed to load. :( Giving up.');
		}
	}

	function Bootstrap_WMEKML() {
		var bGreasemonkeyServiceDefined = false;

		try {
			bGreasemonkeyServiceDefined = ("object" === typeof Components.interfaces.gmIGreasemonkeyService)
		} catch (err) { /* Ignore */ }

		if ("undefined" === typeof unsafeWindow || !bGreasemonkeyServiceDefined) {
			unsafeWindow = (function() {
				var dummyElem = document.createElement('p');
				dummyElem.setAttribute('onclick', 'return window;');
				return dummyElem.onclick();
			})();
		}
		
		setTimeout(Init_WMEKML, 500);
	}

	window.onload = function() {
		Bootstrap_WMEKML();
		$("html").css("visibility", "visible");
	
	}

})();