// ==UserScript==
// @name WME Review Edits (Beta)
// @namespace https://greasyfork.org/en/scripts/382070-wme-reviewedits
// @version 2021.08.26.01
// @description copies information from WME and adds to google sheet for record of reviewed edits.
// @author ramblinwreck_81
// @include https://www.waze.com/en-US/editor*
// @exclude https://www.waze.com/user/editor*
// @grant none
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// ==/UserScript==
(function() {
'use strict';
var RE_Name = GM_info.script.name;
var RE_Version = GM_info.script.version;
var settings = {};
var venuesObject;
var eID;
var rank;
var geoOffset = 'nada';
function RE_log(message) {
console.log(`Review Edits: ${message}`);
}
function bootstrap(tries) {
RE_log(`bootstrap`);
tries = tries || 1;
if (W && W.map &&
W.model && W.loginManager.user &&
$ ) {
RE_init();
// tabBuilder();
} else if (tries < 1000) {
setTimeout(function () {bootstrap(tries++);}, 200);
}
}
bootstrap();
function RE_init() {
// Check document elements are ready
var userInfo = document.getElementById("user-info");
var newEdName = "";
if (userInfo === null) {
window.setTimeout(RE_init, 500);
return;
}
var userTabs = document.getElementById("user-tabs");
if (userTabs === null) {
window.setTimeout(RE_init, 500);
return;
}
var navTab = userInfo.getElementsByTagName("ul");
if (navTab.length === 0) {
window.setTimeout(RE_init, 500);
return;
}
if (typeof navTab[0] === "undefined") {
window.setTimeout(RE_init, 500);
return;
}
var tabContent = userInfo.getElementsByTagName("div");
if (tabContent.length === 0) {
window.setTimeout(RE_init, 500);
return;
}
if (typeof tabContent[0] === "undefined") {
window.setTimeout(RE_init, 500);
return;
}
var editorURL = '';
RE_addUserTab();
RE_addFormBtn();
function RE_addFormBtn() {
RE_log(`adding form button`);
var selection = W.selectionManager.getSelectedFeatures();
var REDiv = document.createElement("div"),
REMnu = document.createElement("select"),
REBtn = document.createElement("button");
var formWindowName = "Review Edits result",
formWindowSpecs = "resizable=1,menubar=0,scrollbars=1,status=0,toolbar=0";
var editPanel,
selElem,
formLink;
REDiv.id = "reviewEditsDiv";
editPanel = document.getElementById("edit-panel");
selElem = editPanel.getElementsByClassName("selection");
if (selection.length === 0) { // || selection[0].model.type !== "segment") {
//formfiller_log("No segments selected.");
return;
}
if (document.getElementById("reviewEditsDiv")) {
//formfiller_log("Div already created");
return;
}
var forms = [{
name: "SER Editor Review",
// testing url: "https://docs.google.com/forms/d/e/1FAIpQLSepKZpDjeHySl95eArUn5iwTuOTUPvpz0ZvqaHg7LbvmBB1Lw/viewform",
url: "https://docs.google.com/forms/d/e/1FAIpQLSfc27FGWsN2RoX8WXYAYZ2xVIkJ1cI8u85ezV--AYsBCVuVKg/viewform",
fields: {
editDate: "150500272",
specificPermalink: "760385393",
reviewingEditor: "1935699410",
sentToEditorPL: "325109063",
editorName: "343499315",
nameOfVenue: "418181794",
editorRank: "986567855"
}
}];
forms.forEach(function (key, i) {
REMnu.options.add(new Option(forms[i].name, i));
});
REBtn.innerHTML = "Go to Form";
REBtn.onclick = function () {
//alert(ffMnu.options[ffMnu.selectedIndex].value+": "+forms[ffMnu.options[ffMnu.selectedIndex].value].name);
RE_saveSettings();
formLink = RE_createFormLink(forms[REMnu.options[REMnu.selectedIndex].value]);
if (typeof formLink === "undefined") {
return;
}
if ($("#RE-open-in-tab").prop("checked")) {
window.open(formLink, "_blank");
} else {
window.open(formLink, formWindowName, formWindowSpecs);
}
};
REDiv.appendChild(REMnu);
REDiv.appendChild(REBtn);
selElem[0].appendChild(REDiv);
return;
} // end of RE_addFormBtn
function createURL(selection)
{
var permalink = "https://www.waze.com/en-US/editor?",
segIDs = [];
var latLon;
var lat;
var lon;
var env = W.location ? W.location.code : W.app.getAppRegionCode();
var zoom = W.map.olMap.zoom;
var latOffset;
var lonOffset;
var zoomOffset;
var type;
var rank = venuesObject.rank + 1;
geoOffset = setGeoOffset(rank);
// zoomOffset = setZoom(rank);
zoomOffset = 0;
if (selection[0].model.type === "venue") { // code for selection is a place venue
RE_log(`Venue selected!`)
if(selection[0].model.isPoint())
{ // get lat and lon for point place
RE_log(`Point Venue selected!`)
var latLon = WazeWrap.Geometry.ConvertTo4326(selection[0].geometry.x, selection[0].geometry.y)
lat = latLon.lat
lon = latLon.lon
} else
{ // get lat and lon for area place
RE_log(`Area Venue selected!`)
latLon = WazeWrap.Geometry.ConvertTo4326(selection[0].model.geometry.getCentroid().x, selection[0].model.geometry.getCentroid().y);
lat = latLon.lat
lon = latLon.lon
}
// permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoom=19&venues=" + W.selectionManager.getSelectedFeatures()[0].model.attributes.id;
permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoomLevel=" + zoom.toString() + "&venues=" + W.selectionManager.getSelectedFeatures()[0].model.attributes.id;
} else { // code for if selection is a segment(s)
type = 'segments'
// var zoomToRoadType = W.Config.segments.zoomToRoadType;
var i;
//To get lat and long centered on segment
if (selection.length === 1) {
latLon = selection[0].model.getCenter().clone();
latLon = WazeWrap.Geometry.ConvertTo4326(latLon.x,latLon.y)
lat = latLon.lat;
lon = latLon.lon;
}
var zoomToRoadType = function (e) {
switch (e) {
case 12:
case 13:
return [];
case 14:
return [2, 3, 4, 6, 7, 15];
case 15:
return [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
default:
return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
}
};
for (i = 0; i < selection.length; i += 1) {
var segment = selection[i].model;
if (segment.type === "segment")
{
segIDs.push(segment.attributes.id);
if (zoomToRoadType(zoom) === 0 || zoomToRoadType(zoom).indexOf(segment.attributes.roadType) === -1)
{
alert("This zoom level (" + zoom.toString() + ") cannot be used for this road type! Please increase your zoom:\n" +
"Streets: 16+\nOther drivable and Non-drivable: 15+\nHighways and PS: 14+");
RE_log("Zoom level not correct for segment: " + zoom.toString() + " " + segment.attributes.roadType.toString());
return;
}
}
}
permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoomLevel=" + zoom.toString() + "&" + type + "=" + segIDs.join();
// permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoom=7&" + type + "=" + segIDs.join();
} // end of model.type if test
latOffset = lat + geoOffset;
lonOffset = lon - geoOffset;
function setZoom(level)
{
switch (level)
{
case 1:
case 2:
zoomOffset = 7;
break;
case 3:
zoomOffset = 6;
break;
case 4:
zoomOffset = 6;
break;
case 5:
case 6:
zoomOffset = 6;
break;
}
return zoomOffset;
}
function setGeoOffset(level)
{
// Added 1/3/20
geoOffset = 0;
return geoOffset;
switch (level)
{
case 1:
case 2 :
geoOffset = .003;
break;
case 3:
geoOffset = .004
break;
case 4:
geoOffset = .005
break;
case 5:
case 6:
geoOffset = .006
break;
}
return geoOffset;
}
var strStartURL = 'https://www.waze.com/en-US/editor?env=usa&lon=';
var correctURL;
var newURL;
editorURL = strStartURL + lonOffset + '&lat=' + latOffset + '&zoomLevel=' + zoomOffset;
return permalink;
} // end of createURL function
function RE_getLastEditor(selection) {
var editorNames = "";
if(selection[0].model.type === "venue") {
if(selection[0].model.attributes.residential) {
return venuesObject.userName;
} else { // it's a venue but not an RPP
// editorNameConcat(selection);
return venuesObject.userName;
}
} else { // it's not a venue, it's a segment or segments
editorNameConcat(selection)
return editorNames;
}
function editorNameConcat(mapObject){
mapObject.forEach(function (selected) {
eID = selected.model.attributes.updatedBy;
if (typeof eID === "undefined") {
RE_log(`Unable to get updatedBy on ${selected.model.attributes.id}`);
eID = selected.model.attributes.createdBy;
}
newEdName = W.model.users.getObjectById(eID).userName;
if (editorNames.indexOf(newEdName) === -1) {
editorNames += ", " + newEdName;
}
});
editorNames = editorNames.substr(2);
return editorNames;
}
}
function RE_createFormLink(formSel) {
var selection = W.selectionManager.getSelectedFeatures();
var formValues = {};
var formFields = formSel.fields;
var formLink = formSel.url + "?entry.";
var formArgs = [];
if (selection.length === 0) { // || selection[0].model.type !== "segment") {
RE_log(`Nothing selected.`);
return;
} else
{
venuesObject = obtainVenuesObject();
//debugger;
checkForVenue();
}
function checkForVenue()
{
if (venuesObject === undefined)
{
setTimeout (function()
{
checkForVenue();
}, 200);
} else
{
completeForm();
return;
}
}
function obtainVenuesObject()
{
var venueEditor;
var a;
var selection = W.selectionManager.getSelectedFeatures();
var eID;
if(selection[0].model.type === "venue" && (selection[0].model.attributes.residential)) {
console.log('RPP');
var objId = selection[0].model.attributes.id;
var objUrl = "https://www.waze.com/Descartes/app/ElementHistory?objectType=venue&objectID=" + objId;
a = $.ajax({
url:objUrl,
datatype: 'json',
success: function(data) {
RE_log(`Descartes API call complete`)
},
async: false
}).responseJSON.users.objects[0];
console.log(a);
return a;
} else { // it's either a point place, area place or segment but not an RPP
eID = selection[0].model.attributes.updatedBy;
if (typeof eID === "undefined") {
RE_log(`Unable to get updatedBy on ${selection[0].model.attributes.id}`);
eID = selection[0].model.attributes.createdBy;
}
venueEditor = W.model.users.getObjectById(eID);
return venueEditor;
}
}
function completeForm()
{
var onePL;
Object.keys(formFields).forEach(function (key, index) {
switch (key) {
case "reviewingEditor":
formValues[key] = W.loginManager.user.userName;
break;
case "specificPermalink":
//debugger;
onePL = createURL(selection);
formValues[key] = onePL;
if (typeof formValues.specificPermalink === "undefined") {
RE_log(`No permalink generated`);
return;
}
break;
case "sentToEditorPL":
//debugger;
formValues[key] = onePL;
// formValues[key] = editorURL;
break;
case "editDate":
var a;
if(selection[0].model.attributes.updatedOn === undefined)
{
a = selection[0].model.attributes.createdOn;
} else
{
a = selection[0].model.attributes.updatedOn;
}
var b = new Date(a).toLocaleDateString();
formValues[key] = b;
break;
case "editorName":
var c = RE_getLastEditor(selection);
formValues[key] = c;
break;
case "nameOfVenue":
if(selection[0].model.type === 'venue')
{
if(selection[0].model.attributes.residential)
{
formValues[key] = 'N/A';
} else
{
formValues[key] = selection[0].model.attributes.name;
}
} else {
formValues[key] = 'N/A';
}
break;
case "editorRank":
if(selection[0].model.type === 'venue')
{
formValues[key] = venuesObject.rank + 1;
} else
{
formValues[key] = W.model.users.getObjectById(eID).rank + 1;
}
break;
default:
RE_log(`Nothing defined for ${key}`);
break;
}
//Add entry to form URL, if there's something to add
if (typeof formValues[key] !== "undefined" && formValues[key] !== "") {
formArgs[index] = formFields[key] + "=" + encodeURIComponent(formValues[key]);
}
});
}
formLink += formArgs.join("&entry.");
RE_log(`${formLink}`);
return formLink;
} // end of createFormLink
var reviewEditsObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
// Mutation is a NodeList and doesn't support forEach like an array
for (var i = 0; i < mutation.addedNodes.length; i += 1) {
var addedNode = mutation.addedNodes[i];
// Only fire up if it's a node
if (addedNode.nodeType === Node.ELEMENT_NODE) {
var selectionDiv = addedNode.querySelector("div.selection");
if (selectionDiv) {
RE_addFormBtn();
}
}
}
});
});
reviewEditsObserver.observe(document.getElementById("edit-panel"), {
childList: true,
subtree: true
});
if (W.app.modeController) {
W.app.modeController.model.bind("change:mode", function (model, modeId) {
if (modeId === 0) {
//debugger;
RE_addUserTab();
}
});
}
// Unit switched (imperial/metric)
if (W.prefs) {
//debugger;
W.prefs.on("change:isImperial", RE_addUserTab);
}
if (!W.selectionManager.getSelectedFeatures) {
W.selectionManager.getSelectedFeatures = W.selectionManager.getSelectedItems;
}
RE_log(`Init done`);
return;
} //end of RE_init
function tabBuilder()
{
var $section = $("<div>");
$section.html([
'<div>',
'<h2>RE_Tab</h2>',
'<input type="checkbox" id="RE_Enabled" class="RE_SettingsCheckbox"><label for="RE_Enabled">Enable This Script</label>',
'<hr>',
'<hr>',
'<div>',
'</div>',
'</div>'
].join(' '));
} // end of tabBuilder function
function RE_addUserTab() {
RE_log(`adding tab`);
var userInfo = document.getElementById("user-info"),
userTabs = document.getElementById("user-tabs"),
navTabs = userTabs.getElementsByClassName("nav-tabs"),
tabContent = userInfo.getElementsByClassName("tab-content");
var RETab = document.createElement("li"),
REPanel = document.createElement("div"),
RENewTabBox = document.createElement("input"),
RENewTabLabel = document.createElement("label"),
RETabInfo = document.createElement("div");
RETab.innerHTML = '<a title="Review Edits" href="#sidepanel-reviewEdits" data-toggle="tab">Review Edits</a>';
REPanel.id = "sidepanel-reviewEdits";
REPanel.className = "tab-pane";
RE_log(`name: ${RE_Name}, Version: ${RE_Version}`);
RETabInfo.innerHTML = '<b>' + RE_Name + '</b> v' + RE_Version;
RENewTabBox.id = "RE-open-in-tab";
RENewTabBox.type = "checkbox";
RENewTabBox.name = "RE_open_tab";
RENewTabLabel.innerHTML = "Open form in new tab";
RENewTabLabel.for = "RE_open_tab";
REPanel.appendChild(RETabInfo);
REPanel.appendChild(RENewTabBox);
REPanel.appendChild(RENewTabLabel);
navTabs[0].appendChild(RETab);
tabContent[0].appendChild(REPanel);
RE_loadSettings();
}
function RE_loadSettings() {
var REOpenInTab = localStorage.getItem("RE-open-in-tab");
if (REOpenInTab === "1") {
$("#RE-open-in-tab").trigger("click");
}
return;
}
function RE_saveSettings() {
if ($("#RE-open-in-tab").prop("checked")) {
localStorage.setItem("RE-open-in-tab", "1");
} else {
localStorage.setItem("RE-open-in-tab", "0");
}
return;
}
})();