// ==UserScript==
// @name WME Keep My Layers
// @description Automatically detects when you've clicked on a layer-infected PL and resets layers in WME to previously saved state.
// @namespace https://greasyfork.org/users/11629-TheLastTaterTot
// @version 0.1.1
// @grant none
// @match https://editor-beta.waze.com/*editor/*
// @match https://www.waze.com/*editor/*
// @author TheLastTaterTot
// ==/UserScript==
(function() {
// -----------------------------------------------------------------------------
//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: No uniqueName found for "' + L[l].name + '"');
console.log('WMEKML: Relying on accelerator id, "' + layerName + '"');
layerSwitcherPanel.accelerator[layerName] = l;
}
}
}
return layerSwitcherPanel
}
// -----------------------------------------------------------------------------
function ResetLayersToSaved() { // TODO: Add option of restoring add'l layers
// not saved by WME in localStorage.
// Fix saved WME layers settings in localStorage
var L = Waze.map.layers,
j, layerNames, numLayers, lname,
layerSwitcherPanel = GetWazeMapLayersFromSwitcher(L),
uniqueNames = layerSwitcherPanel.uniqueName,
visibilityFromWazeLocalStorage;
visibilityFromWazeLocalStorage = JSON.parse(localStorage.layerVisibility); // TODO: maybe add a check for this... tho it's probably unlikely for it to not exist...
$.extend(true, visibilityFromWazeLocalStorage, KML_myLayers.visibilityFromWazeLocalStorage);
// Save it
localStorage.layerVisibility = JSON.stringify(visibilityFromWazeLocalStorage);
// Now fix layer visibility on the map
layerNames = Object.keys(visibilityFromWazeLocalStorage);
numLayers = layerNames.length;
for (j = numLayers; j--;) {
lname = layerNames[j];
// Check that this layer exists in WME...
/* [Note]: Checking from the layerSwitcherPanel object bc that one
as just built, whereas visibilityFromWazeLocalStorage is mixed
with settings saved by WMEKML... which potentially could be
outdated. TODO: check if WME will automatically update the
localStorage to remove layer visibility settings that are no
longer relevant to WME. If this ends up being true, this may
also mean it is unnecessary to update the object and save it
back into localStorage... TBD... */
if (uniqueNames[lname] !== undefined) {
L[uniqueNames[lname]].setVisibility(visibilityFromWazeLocalStorage[lname]);
} // TODO: might want to consider removing layers from localStorage
// or maybe alerting the editor to suggest resaving their layer
// presets in WMEKML....
}
}
// -------------------------------------------------------------------------
/* The following block of code currently has not been implemented.
It will eventually be used to temporarily prevent disabling of those
layers for the duration of the _session_ */
// "satellite_imagery", "cities", "roads", "gps_points", "area_managers", "landmarks",
// "place_updates", "big_junctions", "speed_cameras", "problems", "update_requests",
// "editable_areas", "closures", "live_users", "junctions"
function CheckForNeededLayers() {
switch (true) {
case permalink.search(/&mapUpdateRequest/) > 0:
return "update_requests"
case permalink.search(/&venues/) > 0:
return "landmarks"
case permalink.search(/&mapProblem/) > 0:
return "problems"
default:
return false
}
}
// -------------------------------------------------------------------------
// TODO: Remove KML_myLayers from global later
// TODO: function for temporarily reverting to the layers provided by PL
// TODO: Settings panel for WMEKML that will allow disabling of auto-layers in PL detection
// TODO: Manual trigger of layer reset
// -------------------------------------------------------------------------
function SaveMyVisibleLayers() {
//KML_myLayers = {};
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.push(lname);
}
}
// 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);
}
/*
function KMLSettingsPanel() {
// get dimensions of waze map area
wazeMapHeight = $("#WazeMap").height();
wazeMapWidth = $("#WazeMap").width();
// Expect height of LR panel to be (numLayers*18px)+200px top and bottom
minHeight = 400; //px
lineHeight = 18; //px
headerHeight = 100; //px
footerHeight = 100; //px
listHeight = lineHeight*numLayers;
panelHeight = listHeight + footerHeight + headerHeight;
panelHalfHeight = parseInt(panelHeight/2);
panelWidth = 500;
panelHalfWidth = parseInt(panelWidth/2);
panelTop = parseInt(wazeMapHeight/2)-panelHalfHeight;
panelLeft = parseInt(wazeMapWidth/2)-panelHalfWidth;
layerResetPanelCSS =
'.kml-panel { position: fixed; top: ' + panelTop + '; left: ' + panelLeft +
'; width: ' + panelWidth + '; height: ' + panelHeight + '; ' +
'overflow-y: auto; overflow-x: hidden;' +
'background-color: white; border: 0; border-radius: 10px; box-shadow: 0px 5px 10px #000000; }'
// setup checkbox list for UI
for (l = 0; l < numLayers; l++) {
layersListUI += '<input type="checkbox" id="cbLR_"' + l + '>' +
layerNames[l] + '<br>';
}
}
*/
// -----------------------------------------------------------------------------
function LookForSavedLayerSettings() {
switch (true) {
case typeof KML_myLayers !== "undefined":
console.debug('WMEKML: Found KML_myLayers already declared.')
break;
return true
case localStorage.WME_KeepMyLayers !== undefined:
console.debug('WMEKML: Found saved settings to load!')
KML_myLayers = JSON.parse(localStorage.WME_KeepMyLayers);
return true
default:
/* TODO: Call to popup of instructions for saving default layers set will maybe go here */
return false
}
}
function UserResetOfLayersToSaved() {}
function AutoDetectLayersInPermalink() {
permalink = location.href;
if (permalink.search(/&layers=/) > 0) {
if (LookForSavedLayerSettings()) {
ResetLayersToSaved(CheckForNeededLayers());
}
}
}
function InitKMLButtons() {
// CSS for WMEKML
saveIconCSS =
'i.kml-icn { position: relative; display: inline-block; padding-left: 3px;; padding-right: 3px; }' + //right: 30px; top: 10px; 'width: 12px; height: 12px;
'div.kml-icn { position: absolute; display: inline-block; bottom: 10px; right: 0px; padding: 0; margin: 0px 10px 0px 0px; }' +
'.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; }';
var kmlCSS = document.createElement("style");
kmlCSS.type = "text/css";
kmlCSS.innerHTML = saveIconCSS;
document.body.appendChild(kmlCSS);
// Add save layers icon to Layers switcher dropdown panel
$("#layer-switcher-list").after('<div class="kml-icn">' +
'<a id="aKMLsettings" href="javascript:void(0)" class="kml-icn"><i id="iKMLsettings" class="icon-fixed-width icon-cogs reload-button"></i></a>' +
'<a id="aKMLsaveLayers" href="javascript:void(0)" class="kml-icn"><i id="iKMLsaveLayers" class="icon-fixed-width icon-save reload-button"></i></a>' +
'</div>');
// Setup event listeners
$("a#aKMLsaveLayers").click(SaveMyVisibleLayers);
}
// =============================================================================
var initCount = 0;
function Init_WMEKML() {
if (initCount < 20) {
initCount++;
try {
if ("undefined" !== typeof Waze && Waze.map && Waze.map.layers) {
console.debug('WMEKML: WME Keep My Layers is initializing...')
AutoDetectLayersInPermalink();
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);
}
Bootstrap_WMEKML();
})();