// ==UserScript==
// @name WME Road Selector
// @description Makes selection of multiple roads based on given condition
// @include https://www.waze.com/editor/*
// @include https://www.waze.com/*/editor/*
// @include https://editor-beta.waze.com/*
// @version 0.5
// @grant none
// @copyright 2014, pvo11
// @namespace https://gf.qytechs.cn/scripts/3462-wme-road-selector
// ==/UserScript==
roadSelector_version = '0.5';
var StringOps = {
0: "=",
1: "!=",
2: "contains",
3: "! contains"
};
function populateStringOps(sel)
{
var selectStringOp = getId(sel);
for (var id in StringOps) {
var txt = StringOps[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 0) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectStringOp.appendChild(usrOption);
}
}
var IntegerOps = {
0: "=",
1: "!=",
2: ">",
3: ">=",
4: "<",
5: "<="
};
function populateIntegerOps(sel)
{
var selectIntegerOp = getId(sel);
for (var id in IntegerOps) {
var txt = IntegerOps[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 0) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectIntegerOp.appendChild(usrOption);
}
}
var EqualOps = {
0: "=",
1: "!="
};
function populateEqualOps(sel)
{
var selectEqualOp = getId(sel);
for (var id in EqualOps) {
var txt = EqualOps[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 0) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectEqualOp.appendChild(usrOption);
}
}
var Countries = new Object();
function populateCountries(sel)
{
var selectCountry = getId(sel);
Countries = new Object();
for (var countryID in Waze.model.countries.objects) {
Countries[countryID] = Waze.model.countries.get(countryID).name;
}
for (var id in Countries) {
var txt = Countries[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectCountry.appendChild(usrOption);
}
}
var RoadTypes = {
101: "--- Highways ---",
3: "Freeway",
6: "Major Highway",
7: "Minor Highway",
4: "Ramp",
102: "--- Streets ---",
2: "Primary Street",
1: "Street",
21: "Service Road",
103: "--- Other drivable ---",
8: "Dirt road / 4x4",
20: "Parking Lot",
17: "Private Road",
104: "--- Non-drivable ---",
5: "Walking Trail",
10: "Pedestrian Bw.",
16: "Stairway",
18: "Railroad",
19: "Runway/Taxiway",
14: "Ferry"
};
var RoadTypesOrder = [101, 3, 6, 7, 4, 102, 2, 1, 21, 103, 8, 20, 17, 104, 5, 10, 16, 18, 19, 14];
function populateRoadTypes(sel)
{
var selectRoadType = getId(sel);
for (i = 0; i < RoadTypesOrder.length; i++) {
var id = RoadTypesOrder[i];
var txt = RoadTypes[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id == 1) {
usrOption.setAttribute('selected',true);
}
if (id > 100) {
usrOption.setAttribute('disabled',true);
usrOption.setAttribute('style','font-weight: bold');
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectRoadType.appendChild(usrOption);
}
}
var Directions = {
0: "Two way (=)",
1: "One way (A->B)",
2: "One way (B->A)",
3: "Unknown"
};
function populateDirections(sel)
{
var selectDirection = getId(sel);
for (var id in Directions) {
var txt = Directions[id];
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 0) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectDirection.appendChild(usrOption);
}
}
function populateElevations(sel)
{
var selectElevation = getId(sel);
for (var id = 9; id >= -5; id--) {
var txt;
if (id === 0) {
txt = "Ground";
} else {
txt = String(id);
}
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 0) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectElevation.appendChild(usrOption);
}
}
function populateLocks(sel)
{
var selectLock = getId(sel);
for (var id = 1; id <= 6; id++) {
var txt = String(id);
var usrOption = document.createElement('option');
var usrText = document.createTextNode(txt);
if (id === 1) {
usrOption.setAttribute('selected',true);
}
usrOption.setAttribute('value',id);
usrOption.appendChild(usrText);
selectLock.appendChild(usrOption);
}
}
var ExprStatus = 0;
var ExprTree = new Object();
var BktTrees = new Object();
var BktCount = 0;
var hasStates;
var lang;
function checkExpr(tree, segment)
{
if (typeof (tree.type) === 'undefined') {
return false;
}
var result;
switch (tree.type) {
case "Country":
var sid = segment.attributes.primaryStreetID;
if (typeof(sid) === 'undefined' || sid === null) {
result = false;
} else {
var street = Waze.model.streets.get(sid);
var countryID = Waze.model.cities.get(street.cityID).countryID;
if (tree.op === "0") {
result = tree.id == countryID;
} else {
result = tree.id != countryID;
}
}
break;
case "State":
var sid = segment.attributes.primaryStreetID;
if (typeof(sid) === 'undefined' || sid === null) {
result = false;
} else {
var street = Waze.model.streets.get(sid);
var stateID = Waze.model.cities.get(street.cityID).stateID;
var stateName = Waze.model.states.get(stateID).name;
if (stateName === null) {
stateName = "";
}
switch (tree.op) {
case "0":
result = stateName.localeCompare(tree.txt) === 0;
break;
case "1":
result = stateName.localeCompare(tree.txt) !== 0;
break;
case "2":
result = stateName.indexOf(tree.txt) >= 0;
break;
default:
result = stateName.indexOf(tree.txt) < 0;
break;
}
}
break;
case "City":
var sid = segment.attributes.primaryStreetID;
if (typeof(sid) === 'undefined' || sid === null) {
result = false;
} else {
var street = Waze.model.streets.get(sid);
var cityName = Waze.model.cities.get(street.cityID).name;
if (cityName === null) {
cityName = "";
}
switch (tree.op) {
case "0":
result = cityName.localeCompare(tree.txt) === 0;
break;
case "1":
result = cityName.localeCompare(tree.txt) !== 0;
break;
case "2":
result = cityName.indexOf(tree.txt) >= 0;
break;
default:
result = cityName.indexOf(tree.txt) < 0;
break;
}
}
break;
case "ACity":
result = false;
for(i = 0; i < segment.attributes.streetIDs.length; i++){
var sid = segment.attributes.streetIDs[i];
if (sid === null) {
continue;
} else {
var street = Waze.model.streets.get(sid);
var cityName = Waze.model.cities.get(street.cityID).name;
if (cityName === null) {
cityName = "";
}
switch (tree.op) {
case "0":
result = cityName.localeCompare(tree.txt) === 0;
break;
case "1":
result = cityName.localeCompare(tree.txt) !== 0;
break;
case "2":
result = cityName.indexOf(tree.txt) >= 0;
break;
default:
result = cityName.indexOf(tree.txt) < 0;
break;
}
}
}
break;
case "Street":
var sid = segment.attributes.primaryStreetID;
if (typeof(sid) === 'undefined' || sid === null) {
result = false;
} else {
var street = Waze.model.streets.get(sid);
var streetName = street.name;
if (streetName === null) {
streetName = "";
}
switch (tree.op) {
case "0":
result = streetName.localeCompare(tree.txt) === 0;
break;
case "1":
result = streetName.localeCompare(tree.txt) !== 0;
break;
case "2":
result = streetName.indexOf(tree.txt) >= 0;
break;
default:
result = streetName.indexOf(tree.txt) < 0;
break;
}
}
break;
case "AStreet":
result = false;
for(i = 0; i < segment.attributes.streetIDs.length; i++){
var sid = segment.attributes.streetIDs[i];
if (sid === null) {
result = false;
} else {
var street = Waze.model.streets.get(sid);
var streetName = street.name;
if (streetName === null) {
streetName = "";
}
switch (tree.op) {
case "0":
result = streetName.localeCompare(tree.txt) === 0;
break;
case "1":
result = streetName.localeCompare(tree.txt) !== 0;
break;
case "2":
result = streetName.indexOf(tree.txt) >= 0;
break;
default:
result = streetName.indexOf(tree.txt) < 0;
break;
}
}
}
break;
case "NoName":
if (tree.op) {
result = typeof(segment.attributes.primaryStreetID) === 'undefined' || segment.attributes.primaryStreetID === null;
} else {
result = typeof(segment.attributes.primaryStreetID) !== 'undefined' && segment.attributes.primaryStreetID !== null;
}
break;
case "ANoName":
if (tree.op) {
result = segment.attributes.streetIDs.length === 0;
} else {
result = segment.attributes.streetIDs.length > 0;
}
break;
case "RoadType":
if (tree.op === "0") {
result = tree.id == segment.attributes.roadType;
} else {
result = tree.id != segment.attributes.roadType;
}
break;
case "IsRound":
if (tree.op) {
result = segment.attributes.junctionID !== null;
} else {
result = segment.attributes.junctionID === null;
}
break;
case "IsToll":
if (tree.op) {
result = segment.isTollRoad();
} else {
result = !segment.isTollRoad();
}
break;
case "Direction":
var dir = 0;
if (!segment.attributes.fwdDirection) {
dir += 2;
}
if (!segment.attributes.revDirection) {
dir += 1;
}
if (tree.op === "0") {
result = tree.id == dir;
} else {
result = tree.id != dir;
}
break;
case "Elevation":
switch (tree.op) {
case "0":
result = parseInt(tree.id, 10) === segment.attributes.level;
break;
case "1":
result = parseInt(tree.id, 10) !== segment.attributes.level;
break;
case "2":
result = parseInt(tree.id, 10) < segment.attributes.level;
break;
case "3":
result = parseInt(tree.id, 10) <= segment.attributes.level;
break;
case "4":
result = parseInt(tree.id, 10) > segment.attributes.level;
break;
default:
result = parseInt(tree.id, 10) >= segment.attributes.level;
break;
}
break;
case "ManLock":
if (segment.attributes.lockRank === null) {
result = false;
} else {
switch (tree.op) {
case "0":
result = parseInt(tree.id, 10) === segment.attributes.lockRank + 1;
break;
case "1":
result = parseInt(tree.id, 10) !== segment.attributes.lockRank + 1;
break;
case "2":
result = parseInt(tree.id, 10) < segment.attributes.lockRank + 1;
break;
case "3":
result = parseInt(tree.id, 10) <= segment.attributes.lockRank + 1;
break;
case "4":
result = parseInt(tree.id, 10) > segment.attributes.lockRank + 1;
break;
default:
result = parseInt(tree.id, 10) >= segment.attributes.lockRank + 1;
break;
}
}
break;
case "TrLock":
if (segment.attributes.lockRank === null) {
switch (tree.op) {
case "0":
result = parseInt(tree.id, 10) === segment.attributes.rank + 1;
break;
case "1":
result = parseInt(tree.id, 10) !== segment.attributes.rank + 1;
break;
case "2":
result = parseInt(tree.id, 10) < segment.attributes.rank + 1;
break;
case "3":
result = parseInt(tree.id, 10) <= segment.attributes.rank + 1;
break;
case "4":
result = parseInt(tree.id, 10) > segment.attributes.rank + 1;
break;
default:
result = parseInt(tree.id, 10) >= segment.attributes.rank + 1;
break;
}
} else {
result = false;
}
break;
case "IsNew":
if (tree.op) {
result = segment.isNew();
} else {
result = !segment.isNew();
}
break;
case "IsChngd":
if (tree.op) {
result = !segment.isUnchanged();
} else {
result = segment.isUnchanged();
}
break;
case "OnScr":
if (tree.op) {
result = segment.onScreen();
} else {
result = !segment.onScreen();
}
break;
case "Updtd":
var name;
if (typeof(segment.attributes.updatedBy) === 'undefined' || sid === null) {
name = '';
} else {
name = Waze.model.users.get(segment.attributes.updatedBy).userName;
if ((typeof(name) === "undefined") || (name === null)) {
return false;
}
}
switch (tree.op) {
case "0":
result = name.localeCompare(tree.txt) === 0;
break;
case "1":
result = name.localeCompare(tree.txt) !== 0;
break;
case "2":
result = name.indexOf(tree.txt) >= 0;
break;
default:
result = name.indexOf(tree.txt) < 0;
break;
}
break;
case "Crtd":
var name;
if (typeof(segment.attributes.createdBy) === 'undefined' || sid === null) {
name = '';
} else {
name = Waze.model.users.get(segment.attributes.createdBy).userName;
if ((typeof(name) === "undefined") || (name === null)) {
return false;
}
}
switch (tree.op) {
case "0":
result = name.localeCompare(tree.txt) === 0;
break;
case "1":
result = name.localeCompare(tree.txt) !== 0;
break;
case "2":
result = name.indexOf(tree.txt) >= 0;
break;
default:
result = name.indexOf(tree.txt) < 0;
break;
}
break;
case "LastU":
var updatedDays;
if (typeof(segment.attributes.updatedOn) === 'undefined' || sid === null) {
updatedDays = 0;
} else {
updatedDays = Math.floor((new Date().getTime() - segment.attributes.updatedOn) / 86400000);
}
switch (tree.op) {
case "0":
result = parseInt(tree.txt, 10) === updatedDays;
break;
case "1":
result = parseInt(tree.txt, 10) !== updatedDays;
break;
case "2":
result = parseInt(tree.txt, 10) < updatedDays;
break;
case "3":
result = parseInt(tree.txt, 10) <= updatedDays;
break;
case "4":
result = parseInt(tree.txt, 10) > updatedDays;
break;
default:
result = parseInt(tree.txt, 10) >= updatedDays;
break;
}
break;
case "And":
if (checkExpr (tree.L, segment)) {
result = checkExpr (tree.R, segment);
} else {
result = false;
}
break;
case "Or":
if (checkExpr (tree.L, segment)) {
result = true;
} else {
result = checkExpr (tree.R, segment);
}
break;
case "Not":
result = !checkExpr (tree.R, segment);
break;
case "Bkt":
result = checkExpr (tree.L, segment);
break;
default:
result = false;
break;
}
return result;
}
function genExptrTxt(tree)
{
if (typeof (tree.type) === 'undefined') {
return "";
}
var result;
switch (tree.type) {
case "Country":
result = 'Country ' + EqualOps[tree.op] + ' "' + Countries[tree.id] + '"';
break;
case "State":
case "City":
case "Street":
result = tree.type + ' ';
switch (tree.op) {
case "0":
case "1":
result += StringOps[tree.op] + ' "' + tree.txt + '"';
break;
default:
result += StringOps[tree.op] + ' ("' + tree.txt + '")';
break;
}
break;
case "ACity":
result = 'Alt. City ';
switch (tree.op) {
case "0":
case "1":
result += StringOps[tree.op] + ' "' + tree.txt + '"';
break;
default:
result += StringOps[tree.op] + ' ("' + tree.txt + '")';
break;
}
break;
case "AStreet":
result = 'Alt. Street ';
switch (tree.op) {
case "0":
case "1":
result += StringOps[tree.op] + ' "' + tree.txt + '"';
break;
default:
result += StringOps[tree.op] + ' ("' + tree.txt + '")';
break;
}
break;
case "NoName":
if (tree.op) {
result = 'Unnamed';
} else {
result = 'Has name';
}
break;
case "ANoName":
if (tree.op) {
result = 'NO Alt. names';
} else {
result = 'Has Alt. name(s)';
}
break;
case "RoadType":
result = 'Road Type ' + EqualOps[tree.op] + ' "' + RoadTypes[tree.id] + '"';
break;
case "IsToll":
if (tree.op) {
result = 'Is Toll Road';
} else {
result = 'Is NOT Toll Road';
}
break;
case "IsRound":
if (tree.op) {
result = 'Is Roundabout';
} else {
result = 'Is NOT Roundabout';
}
break;
case "Direction":
result = 'Direction ' + EqualOps[tree.op] + ' "' + Directions[tree.id] + '"';
break;
case "Elevation":
if (tree.id == 0) {
result = 'Elevation ' + IntegerOps[tree.op] + ' "Ground"';
} else {
result = 'Elevation ' + IntegerOps[tree.op] + ' ' + tree.id;
}
break;
case "ManLock":
result = 'Manual Locks ' + IntegerOps[tree.op] + ' ' + tree.id;
break;
case "TrLock":
result = 'Trafic Locks ' + IntegerOps[tree.op] + ' ' + tree.id;
break;
case "IsNew":
if (tree.op) {
result = 'Is New ';
} else {
result = 'Is NOT New';
}
break;
case "IsChngd":
if (tree.op) {
result = 'Is Changed ';
} else {
result = 'Is NOT Changed ';
}
break;
case "OnScr":
if (tree.op) {
result = 'On Screen ';
} else {
result = 'OUT of Screen ';
}
break;
case "Updtd":
result = 'Updated by ';
switch (tree.op) {
case "0":
case "1":
result += StringOps[tree.op] + ' "' + tree.txt + '"';
break;
default:
result += StringOps[tree.op] + ' ("' + tree.txt + '")';
break;
}
break;
case "Crtd":
result = 'Created by ';
switch (tree.op) {
case "0":
case "1":
result += StringOps[tree.op] + ' "' + tree.txt + '"';
break;
default:
result += StringOps[tree.op] + ' ("' + tree.txt + '")';
break;
}
break;
case "LastU":
result = 'Last update ' + IntegerOps[tree.op] + ' ' + tree.txt + ' days ago';
break;
case "And":
result = genExptrTxt(tree.L) + ' AND ';
if (typeof (tree.R) !== 'undefined') {
result += genExptrTxt(tree.R);
}
break;
case "Or":
result = genExptrTxt(tree.L) + ' OR ';
if (typeof (tree.R) !== 'undefined') {
result += genExptrTxt(tree.R);
}
break;
case "Not":
result = '! ';
if (typeof (tree.R) !== 'undefined') {
result += genExptrTxt(tree.R);
}
break;
case "Bkt":
result = '(';
result += genExptrTxt(tree.L) + ')';
break;
default:
result = "";
break;
}
return result;
}
function displayExpr()
{
var ExprTxt = "";
for (var i = 0; i < BktCount; i ++) {
ExprTxt += genExptrTxt(BktTrees[i]) + "(";
}
ExprTxt += genExptrTxt(ExprTree);
getId("outRSExpr").value = ExprTxt;
}
function displayStatus()
{
if (ExprStatus === 0 || ExprStatus === 2) {
getId("btnRSAddCountry").disabled = false;
getId("btnRSAddCity").disabled = false;
getId("btnRSAddStreet").disabled = false;
getId("btnRSAddNoName").disabled = false;
getId("btnRSAddRoadType").disabled = false;
getId("btnRSAddIsRound").disabled = false;
getId("btnRSAddIsToll").disabled = false;
getId("btnRSAddDirection").disabled = false;
getId("btnRSAddElevation").disabled = false;
getId("btnRSAddManLock").disabled = false;
getId("btnRSAddTrLock").disabled = false;
getId("btnRSAddIsNew").disabled = false;
getId("btnRSAddIsChngd").disabled = false;
getId("btnRSAddOnScr").disabled = false;
getId("btnRSAddUpdtd").disabled = false;
getId("btnRSAddCrtd").disabled = false;
getId("btnRSAddLastU").disabled = false;
getId("btnRSAnd").disabled = true;
getId("btnRSOr").disabled = true;
if (ExprStatus === 2) {
getId("btnRSNot").disabled = true;
} else {
getId("btnRSNot").disabled = false;
}
getId("btnRSLBkt").disabled = false;
getId("btnRSRBkt").disabled = true;
getId("btnRSSelect").disabled = true;
} else {
getId("btnRSAddCountry").disabled = true;
getId("btnRSAddCity").disabled = true;
getId("btnRSAddStreet").disabled = true;
getId("btnRSAddNoName").disabled = true;
getId("btnRSAddRoadType").disabled = true;
getId("btnRSAddIsRound").disabled = true;
getId("btnRSAddIsToll").disabled = true;
getId("btnRSAddDirection").disabled = true;
getId("btnRSAddElevation").disabled = true;
getId("btnRSAddManLock").disabled = true;
getId("btnRSAddTrLock").disabled = true;
getId("btnRSAddIsNew").disabled = true;
getId("btnRSAddIsChngd").disabled = true;
getId("btnRSAddOnScr").disabled = true;
getId("btnRSAddUpdtd").disabled = true;
getId("btnRSAddCrtd").disabled = true;
getId("btnRSAddLastU").disabled = true;
getId("btnRSAnd").disabled = false;
getId("btnRSOr").disabled = false;
getId("btnRSNot").disabled = true;
getId("btnRSLBkt").disabled = true;
if (BktCount === 0) {
getId("btnRSRBkt").disabled = true;
getId("btnRSSelect").disabled = false;
} else {
getId("btnRSRBkt").disabled = false;
getId("btnRSSelect").disabled = true;
}
}
getId("outRSNumBkt").value = BktCount;
displayExpr();
}
function addCondition(cond)
{
if (typeof (ExprTree.type) === 'undefined') {
ExprTree = cond;
} else {
if (typeof (ExprTree.R) === 'undefined') {
ExprTree.R = cond;
} else {
ExprTree.R.R = cond;
}
}
ExprStatus = 1;
displayStatus ();
}
function makeCountry(ev)
{
var cond = new Object();
cond.type = "Country";
cond.op = getId("opRSCountry").value;
cond.id = getId("selRSCountry").value;
addCondition(cond);
}
function makeState(ev)
{
var cond = new Object();
cond.type = "State";
cond.op = getId("opRSState").value;
cond.txt = getId("inRSState").value;
addCondition(cond);
}
function makeCity(ev)
{
var cond = new Object();
if (getId("cbRSAlter").checked) {
cond.type = "ACity";
} else {
cond.type = "City";
}
cond.op = getId("opRSCity").value;
cond.txt = getId("inRSCity").value;
addCondition(cond);
}
function makeStreet(ev)
{
var cond = new Object();
if (getId("cbRSAlter").checked) {
cond.type = "AStreet";
} else {
cond.type = "Street";
}
cond.op = getId("opRSStreet").value;
cond.txt = getId("inRSStreet").value;
addCondition(cond);
}
function makeNoName(ev)
{
var cond = new Object();
if (getId("cbRSAlter").checked) {
cond.type = "ANoName";
} else {
cond.type = "NoName";
}
cond.op = getId("cbRSNoName").checked;
addCondition(cond);
}
function makeRoadType(ev)
{
var cond = new Object();
cond.type = "RoadType";
cond.op = getId("opRSRoadType").value;
cond.id = getId("selRSRoadType").value;
addCondition(cond);
}
function makeIsRound(ev)
{
var cond = new Object();
cond.type = "IsRound";
cond.op = getId("cbRSIsRound").checked;
addCondition(cond);
}
function makeIsToll(ev)
{
var cond = new Object();
cond.type = "IsToll";
cond.op = getId("cbRSIsToll").checked;
addCondition(cond);
}
function makeDirection(ev)
{
var cond = new Object();
cond.type = "Direction";
cond.op = getId("opRSDirection").value;
cond.id = getId("selRSDirection").value;
addCondition(cond);
}
function makeElevation(ev)
{
var cond = new Object();
cond.type = "Elevation";
cond.op = getId("opRSElevation").value;
cond.id = getId("selRSElevation").value;
addCondition(cond);
}
function makeManLock(ev)
{
var cond = new Object();
cond.type = "ManLock";
cond.op = getId("opRSManLock").value;
cond.id = getId("selRSManLock").value;
addCondition(cond);
}
function makeTrLock(ev)
{
var cond = new Object();
cond.type = "TrLock";
cond.op = getId("opRSTrLock").value;
cond.id = getId("selRSTrLock").value;
addCondition(cond);
}
function makeIsNew(ev)
{
var cond = new Object();
cond.type = "IsNew";
cond.op = getId("cbRSIsNew").checked;
addCondition(cond);
}
function makeIsChngd(ev)
{
var cond = new Object();
cond.type = "IsChngd";
cond.op = getId("cbRSIsChngd").checked;
addCondition(cond);
}
function makeOnScr(ev)
{
var cond = new Object();
cond.type = "OnScr";
cond.op = getId("cbRSOnScr").checked;
addCondition(cond);
}
function makeUpdtd(ev)
{
var cond = new Object();
cond.type = "Updtd";
cond.op = getId("opRSUpdtd").value;
cond.txt = getId("inRSUpdtd").value;
addCondition(cond);
}
function makeCrtd(ev)
{
var cond = new Object();
cond.type = "Crtd";
cond.op = getId("opRSCrtd").value;
cond.txt = getId("inRSCrtd").value;
addCondition(cond);
}
function makeLastU(ev)
{
var cond = new Object();
cond.type = "LastU";
cond.op = getId("opRSLastU").value;
cond.txt = getId("inRSLastU").value;
if (isNaN(parseInt(cond.txt, 10))) {
cond.txt = '1';
}
addCondition(cond);
}
function makeAnd(ev)
{
var op = new Object();
op.type = "And";
if (ExprTree.type === "Or") {
if (typeof (ExprTree.R) !== 'undefined') {
op.L = ExprTree.R;
}
ExprTree.R = op;
} else {
op.L = ExprTree;
ExprTree = op;
}
ExprStatus = 0;
displayStatus ();
}
function makeOr(ev)
{
var op = new Object();
op.type = "Or";
op.L = ExprTree;
ExprTree = op;
ExprStatus = 0;
displayStatus ();
}
function makeNot(ev)
{
var op = new Object();
op.type = "Not";
if (typeof (ExprTree.type) === 'undefined') {
ExprTree = op;
} else {
if (typeof (ExprTree.R) === 'undefined') {
ExprTree.R = op;
} else {
ExprTree.R.R = op;
}
}
ExprStatus = 2;
displayStatus ();
}
function makeLBkt(ev)
{
BktTrees[BktCount] = ExprTree;
ExprTree = new Object;
BktCount ++;
ExprStatus = 0;
displayStatus ();
}
function makeRBkt(ev)
{
BktCount --;
var cond = new Object();
cond.type = "Bkt";
cond.L = ExprTree;
ExprTree = BktTrees[BktCount];
addCondition(cond);
}
function selectRoads()
{
var foundSegs = new Array();
for (var seg in Waze.model.segments.objects) {
var segment = Waze.model.segments.get(seg);
if (segment.arePropertiesEditable() || !getId("cbRSEditable").checked) {
if (checkExpr(ExprTree, segment)) {
foundSegs.push(segment);
}
}
}
Waze.selectionManager.select(foundSegs);
}
function clearExpr(ev)
{
ExprStatus = 0;
ExprTree = new Object();
BktCount = 0;
displayStatus ();
}
function delLast(ev)
{
if (typeof (ExprTree.type) === 'undefined') {
if (BktCount > 0) {
BktCount--;
ExprTree = BktTrees[BktCount];
if (ExprTree.type === "Not") {
ExprStatus = 2;
} else {
ExprStatus = 0;
}
}
} else {
switch (ExprTree.type) {
case "And":
if (typeof (ExprTree.R) === 'undefined') {
ExprTree = ExprTree.L;
ExprStatus = 1;
} else {
if (ExprTree.R.type === "Bkt") {
BktTrees[BktCount] = ExprTree;
ExprTree = ExprTree.R.L;
delete BktTrees[BktCount].R;
BktCount ++;
ExprStatus = 1;
} else if (ExprTree.R.type === "Not") {
if (typeof (ExprTree.R.R) === 'undefined') {
delete ExprTree.R;
ExprStatus = 0;
} else {
delete ExprTree.R.R;
ExprStatus = 2;
}
} else {
delete ExprTree.R;
ExprStatus = 0;
}
}
break;
case "Or":
if (typeof (ExprTree.R) === 'undefined') {
ExprTree = ExprTree.L;
ExprStatus = 1;
} else {
if (ExprTree.R.type === "Bkt") {
BktTrees[BktCount] = ExprTree;
ExprTree = ExprTree.R.L;
delete BktTrees[BktCount].R;
BktCount ++;
ExprStatus = 1;
} else if (ExprTree.R.type === "Not") {
if (typeof (ExprTree.R.R) === 'undefined') {
delete ExprTree.R;
ExprStatus = 0;
} else {
delete ExprTree.R.R;
ExprStatus = 2;
}
} else if (ExprTree.R.type === "And") {
if (typeof (ExprTree.R.R) === 'undefined') {
ExprTree.R = ExprTree.R.L;
ExprStatus = 1;
} else {
delete ExprTree.R.R;
ExprStatus = 0;
}
} else {
delete ExprTree.R;
ExprStatus = 0;
}
}
break;
case "Bkt":
BktTrees[BktCount] = new Object();
ExprTree = ExprTree.L;
BktCount ++;
ExprStatus = 1;
break;
default:
ExprTree = new Object();
ExprStatus = 0;
break;
}
}
displayStatus ();
}
function getElementsByClassName(classname, node)
{
if(!node) {
node = document.getElementsByTagName("body")[0];
}
var a = [];
var re = new RegExp('\\b' + classname + '\\b');
var els = node.getElementsByTagName("*");
for (var i=0,j=els.length; i<j; i++) {
if (re.test(els[i].className)) {
a.push(els[i]);
}
}
return a;
}
function getId(node)
{
return document.getElementById(node);
}
function roadSelector_init()
{
var addon = document.createElement('section');
addon.id = "roadselector-addon";
addon.innerHTML = '<b><u><a href="https://www.waze.com/forum/viewtopic.php?f=22&t=101365#p842165" target="_blank">WME Road Selector</a></u></b> v' + roadSelector_version;
var section = document.createElement('p');
section.style.paddingTop = "8px";
section.style.textIndent = "16px";
section.style.fontSize = "9px";
section.id = "RSconditions";
str = '<font size=3>Conditions</font>'
+ '<table width=100% rules=rows>'
+ '<tr><td><b>Country</b> <select id="opRSCountry" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSCountry" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddCountry" style="padding:0px 10px; height:20px">Add</button></td></tr>';
if (hasStates) {
str += '<tr><td><b>State</b> <select id="opRSState" style="padding:0px 0px; height:20px"></select> '
+ '<input type="text" id="inRSState" size=10 style="padding:0px 0px; height:20px" /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddState" style="padding:0px 10px; height:20px">Add</button></td></tr>';
}
str += '<tr><td><b>City</b> <select id="opRSCity" style="padding:0px 0px; height:20px"></select> '
+ '<input type="text" id="inRSCity" size=10 style="padding:0px 0px; height:20px" /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddCity" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Street</b> <select id="opRSStreet" style="padding:0px 0px; height:20px"></select> '
+ '<input type="text" id="inRSStreet" size=10 style="padding:0px 0px; height:20px" /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddStreet" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Unmamed segment</b> <input type="checkbox" id="cbRSNoName" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddNoName" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Alternate name (City or Street)</b> <input type="checkbox" id="cbRSAlter" style="padding:0px 0px" /></td></tr>'
+ '<tr><td><b>Road type</b> <select id="opRSRoadType" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSRoadType" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddRoadType" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Roundabout</b> <input type="checkbox" id="cbRSIsRound" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddIsRound" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Toll Road</b> <input type="checkbox" id="cbRSIsToll" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddIsToll" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Direction</b> <select id="opRSDirection" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSDirection" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddDirection" style="padding:0px 10px; height:20px">Add</button>'
+ '<tr><td><b>Elevation</b> <select id="opRSElevation" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSElevation" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddElevation" style="padding:0px 10px; height:20px">Add</button>'
+ '<tr><td><b>Manual Lock</b> <select id="opRSManLock" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSManLock" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddManLock" style="padding:0px 10px; height:20px">Add</button>'
+ '<tr><td><b>Trafic Lock</b> <select id="opRSTrLock" style="padding:0px 0px; height:20px"></select> '
+ '<select id="selRSTrLock" style="padding:0px 0px; height:20px"></select></td>'
+ '<td><button class="btn btn-default" id="btnRSAddTrLock" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>New</b> <input type="checkbox" id="cbRSIsNew" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddIsNew" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Changed</b> <input type="checkbox" id="cbRSIsChngd" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddIsChngd" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>On Screen</b> <input type="checkbox" id="cbRSOnScr" style="padding:0px 0px" checked /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddOnScr" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Updated by</b> <select id="opRSUpdtd" style="padding:0px 0px; height:20px"></select> '
+ '<input type="text" id="inRSUpdtd" size=8 style="padding:0px 0px; height:20px" /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddUpdtd" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Created by</b> <select id="opRSCrtd" style="padding:0px 0px; height:20px"></select> '
+ '<input type="text" id="inRSCrtd" size=8 style="padding:0px 0px; height:20px" /></td>'
+ '<td><button class="btn btn-default" id="btnRSAddCrtd" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '<tr><td><b>Last update</b> <select id="opRSLastU" style="padding:0px 0px; height:20px"></select> '
+ '<input type="number" min="0" max="365" value="1" id="inRSLastU" size=3 style="padding:0px 0px; height:20px; display:inline-block"/> <b> days ago </b></td>'
+ '<td><button class="btn btn-default" id="btnRSAddLastU" style="padding:0px 10px; height:20px">Add</button></td></tr>'
+ '</table>'
;
section.innerHTML = str;
addon.appendChild(section);
section = document.createElement('p');
section.style.paddingTop = "8px";
section.style.textIndent = "16px";
section.style.fontSize = "10px";
section.id = "RSoperations";
section.innerHTML = '<font size=3>Operations</font><br>'
+ '<button class="btn btn-default" id="btnRSAnd" style="padding:0px 10px; height:20px">AND</button> '
+ '<button class="btn btn-default" id="btnRSOr" style="padding:0px 10px; height:20px">OR</button> '
+ '<button class="btn btn-default" id="btnRSNot" style="padding:0px 10px; height:20px"> ! </button> '
+ '<button class="btn btn-default" id="btnRSLBkt" style="padding:0px 10px; height:20px"> ( </button> '
+ '<output id="outRSNumBkt" style="padding:0px 0px; height:20px; display:inline-block">0</output> '
+ '<button class="btn btn-default" id="btnRSRBkt" style="padding:0px 10px; height:20px"> ) </button>'
;
addon.appendChild(section);
section = document.createElement('p');
section.style.paddingTop = "8px";
section.style.textIndent = "16px";
section.style.fontSize = "10px";
section.id = "RSselection";
section.innerHTML = '<font size=3>Selection</font><br>'
+ '<output id="outRSExpr"></output><br>'
+ '<input type="checkbox" id="cbRSEditable" style="padding:0px 0px; height:20px" checked /><b> Editable only</b><br><br>;'
+ '<button class="btn btn-default" id="btnRSSelect" style="padding:0px 10px; height:30px"> Select roads </button> '
+ '<button class="btn btn-default" id="btnRSClear" style="padding:0px 10px; height:20px"> Clear </button> '
+ '<button class="btn btn-default" id="btnRSDel" style="padding:0px 10px; height:20px"> Delete last </button>'
;
addon.appendChild(section);
var userTabs = getId('user-info');
var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
var tabContent = getElementsByClassName('tab-content', userTabs)[0];
newtab = document.createElement('li');
newtab.innerHTML = '<a href="#sidepanel-roadselector" data-toggle="tab">Road Selector</a>';
navTabs.appendChild(newtab);
addon.id = "sidepanel-roadselector";
addon.className = "tab-pane";
tabContent.appendChild(addon);
populateEqualOps("opRSCountry");
populateCountries("selRSCountry");
if (hasStates) {
populateStringOps("opRSState");
}
populateStringOps("opRSCity");
populateStringOps("opRSStreet");
populateEqualOps("opRSRoadType");
populateRoadTypes("selRSRoadType");
populateEqualOps("opRSDirection");
populateDirections("selRSDirection");
populateIntegerOps("opRSElevation");
populateElevations("selRSElevation");
populateIntegerOps("opRSManLock");
populateLocks("selRSManLock");
populateIntegerOps("opRSTrLock");
populateLocks("selRSTrLock");
populateStringOps("opRSUpdtd");
populateStringOps("opRSCrtd");
populateIntegerOps("opRSLastU");
displayStatus ();
getId("btnRSAddCountry").onclick = makeCountry;
if (hasStates) {
getId("btnRSAddState").onclick = makeState;
}
getId("btnRSAddCity").onclick = makeCity;
getId("btnRSAddStreet").onclick = makeStreet;
getId("btnRSAddNoName").onclick = makeNoName;
getId("btnRSAddRoadType").onclick = makeRoadType;
getId("btnRSAddIsRound").onclick = makeIsRound;
getId("btnRSAddIsToll").onclick = makeIsToll;
getId("btnRSAddDirection").onclick = makeDirection;
getId("btnRSAddElevation").onclick = makeElevation;
getId("btnRSAddManLock").onclick = makeManLock;
getId("btnRSAddTrLock").onclick = makeTrLock;
getId("btnRSAddIsNew").onclick = makeIsNew;
getId("btnRSAddIsChngd").onclick = makeIsChngd;
getId("btnRSAddOnScr").onclick = makeOnScr;
getId("btnRSAddUpdtd").onclick = makeUpdtd;
getId("btnRSAddCrtd").onclick = makeCrtd;
getId("btnRSAddLastU").onclick = makeLastU;
getId("btnRSAnd").onclick = makeAnd;
getId("btnRSOr").onclick = makeOr;
getId("btnRSNot").onclick = makeNot;
getId("btnRSLBkt").onclick = makeLBkt;
getId("btnRSRBkt").onclick = makeRBkt;
getId("btnRSSelect").onclick = selectRoads;
getId("btnRSClear").onclick = clearExpr;
getId("btnRSDel").onclick = delLast;
}
function roadSelector_wait()
{
if ((typeof(Waze.model.countries.objects) === 'undefined') || (Object.keys(Waze.model.countries.objects).length === 0)) {
setTimeout(roadSelector_wait, 500);
} else {
hasStates = Waze.model.hasStates();
roadSelector_init();
}
}
function roadSelector_bootstrap()
{
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(roadSelector_wait, 1500);
}
roadSelector_bootstrap();