// ==UserScript==
// @name WME Context Menu
// @namespace https://greasyfork.org/users/11629-TheLastTaterTot
// @version 0.3.6
// @description A right-click popup menu for editing segments. Currently integrates with WME Speedhelper and Road Selector to help make it even easier and faster to edit the map.
// @author TheLastTaterTot
// @include https://editor-beta.waze.com/*editor/*
// @include https://www.waze.com/*editor/*
// @exclude https://www.waze.com/*user/editor/*
// @grant none
// @run-at document-end
// ==/UserScript==
/* jshint -W097 */
//--------------- DEBUG ----------------
var DEBUG = false;
function cmlog() {
if (DEBUG) {
var debugStyle, debugCode,
args = arguments,
argArray = Object.keys(args).map(function(key) {
return args[key];
});
if (argArray[0].constructor === Array) {
debugStyle = argArray[0][1];
debugCode = parseInt(argArray[0][0]);
}
if (debugCode === DEBUG) {
argArray = argArray.splice(1);
switch (debugStyle) {
case 1: // examine functions
logCss = 'background: #444; color: #6FF';
break;
case 2: // examine eventListeners
logCss = 'background: #CCC; color: #048';
break;
default:
logCss = 'background: #EEE; color: #000; font-weight: bold;';
}
console.debug('%cWMECM: %s', logCss, argArray.join(' '));
}
}
}
//------------------------------------------------------------------------------
var SL = {
forceBuildNewMenu: true,
menuResetEvent: true,
imperial: {
mphCountries: ['UK', 'US', 'MU', 'AR', 'IC', 'JE', 'GQ', 'CJ', 'BM', 'LI'],
mph2kph: 1.609344,
kph2mph: 0.621371192,
useMPH: null,
convertUnits: null,
currentCountry: null
},
slSavedMaxElementTotal: 0,
slSavedMenuElementFlags: false,
cmMenuContentHTML: null,
signsContainerHTML: null,
speedhelperIsPresent: null,
signsContainerHeight: null
};
var roadTypes = {
1: "Street",
2: "Primary Street",
3: "Freeway",
4: "Ramp",
5: "Walking Trail",
6: "Major Highway",
7: "Minor Highway",
8: "Dirt road / 4X4 Trail",
10: "Pedestrian Boardwalk",
15: "Ferry",
16: "Stairway",
17: "Private Road",
18: "Railroad",
19: "Runway/Taxiway",
20: "Parking Lot Road"
},
menuResetEvent_RSel = false,
contextMenuSettings,
changeEvent = new Event('change', { 'bubbles': true }),
isFirefox = !!~navigator.userAgent.indexOf('irefox'),
minVersion = '0.3.6';
try {
if (isFirefox && localStorage.WME_ContextMenuFF) {
window.alert('WME Context Menu has been updated to be fully functional in FireFox.\n\nThank you for your patience!');
localStorage.removeItem('WME_ContextMenuFF');
}
} catch(err) {}
//------------------------------------------------------------------------------
if (localStorage.WME_ContextMenu) {
contextMenuSettings = JSON.parse(localStorage.WME_ContextMenu);
if (contextMenuSettings.hidden === undefined) {
contextMenuSettings.hidden = {};
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
}
} else {
contextMenuSettings = {
clipboard: 0,
position: 0,
pin: false,
countries: [],
speedSigns: {default: {
speeds: [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130],
signShape: 'Circle',
signBorderColor: '#34444B'
}},
speedhelper: {},
version: 0,
hidden: {}
};
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
}
//------------------------------------------------------------------------------
CMenuVersion = {
currentVersion: GM_info.script.version,
lastVersionString: function(){return contextMenuSettings.version;},
convertToNumericVersion: function(versionString) {
var vMult = [8000, 400, 20, 1],
versionNumeric = 0;
if (versionString) {
if (versionString.constructor === Array) {
if (versionString.length === 1) {
versionString = versionString[0];
} else {
console.error('WMECM:', 'versionString is an array with more than 1 element.');
}
}
return versionString.match(/(\d)+/g).map(function(d, i) {
versionNumeric += d * vMult[i];
}), versionNumeric;
} else {
return null;
}
},
getLastVersionValue: function() {
return this.convertToNumericVersion(this.lastVersionString());
},
updateVersionString: function() {
contextMenuSettings.version = this.currentVersion;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
},
isUpToDate: function(minimumVersionString) {
var minVersionVal = this.convertToNumericVersion(minimumVersionString),
lastVersionVal = this.getLastVersionValue();
return (lastVersionVal >= minVersionVal) ? true : false;
}
};
//------------------------------------------------------------------------------
if (!CMenuVersion.isUpToDate(minVersion)) {
if (contextMenuSettings.speedSigns === undefined) {
contextMenuSettings.speedSigns = {default: {
speeds: [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130],
signShape: 'Circle',
signBorderColor: '#34444B'
}};
contextMenuSettings.speedhelper = {};
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
//---------- TEMP -------------
if (localStorage.contextMenuSettings) localStorage.removeItem('contextMenuSettings');
}
//CMenuVersion.updateVersionString(minVersion);
}
//------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////////
var getUnique = function (objArray) {
var isNotDuplicate = function (comparisonList, checkThisName) {
var isNotDup = true;
try {
for (var c = 0, cLength = comparisonList.length; c < cLength; c++) {
if (comparisonList[c] === checkThisName) isNotDup = false;
}
} catch (err) {
console.error(err);
}
return isNotDup;
};
try {
var uniqObjs = [];
for (var r = objArray.length; r--;) {
if (isNotDuplicate(uniqObjs, objArray[r])) uniqObjs.push(objArray[r]); // && objArray[r] !== ''
}
return uniqObjs;
} catch (err) {
console.error(err);
}
};
//----------------------------------------------------------------------
var addPasteItems = function(attrName) {
if (/primaryStreet|primaryCity/.test(attrName)) {
clipboard = document.getElementById('input_' + attrName);
if (clipboard) {
pasteOption = document.createElement('dd');
pasteOption.className = 'cm-paste';
pasteOption.innerHTML = clipboard.value;
pasteOption.name = clipboard.value;
//$('#'+attrName+'>dt').after('<dd class="cm-paste" name="' + clipboard.value + '">' + clipboard.value +'</dd>');
$('#' + attrName + ' .cm-paste').remove();
if (document.querySelector('#' + attrName + '>dd')){
document.getElementById(attrName).insertBefore(pasteOption, document.querySelector('#' + attrName + '>dd'));
} else {
document.getElementById(attrName).appendChild(pasteOption);
}
pasteOption.addEventListener('click', function(e) { pasteTo(e, this.parentNode.id, this.name); }, false);
}
}
};
var pasteTo = function (e, opt, val) {
try { // (temporary) really dumb way via DOM nodes:
switch (opt) {
case 'cm_primaryStreet':
$('.address-edit-icon').click();
$('#emptyStreet').prop('checked',false).change();
$('.form-control.streetName').val(val).change();
if (!$('.form-control[name=cityName]').val().length) $('#emptyCity').prop('checked',true).change();
if ($('.form-control[name=stateID]').length) $('.form-control[name=stateID]').val(W.model.states.top.id);
if ($('.form-control[name=countryID]').length) $('.form-control[name=countryID]').val(W.model.countries.top.id);
$('.action-buttons>.save-button').click();
break;
case 'cm_primaryCity':
$('.address-edit-icon').click();
$('#emptyCity').prop('checked',false).change();
$('.form-control[name=cityName]').val(val).change();
if (!$('.form-control.streetName').val().length) $('#emptyStreet').prop('checked',true).change();
if ($('.form-control[name=stateID]').length) $('.form-control[name=stateID]').val(W.model.states.top.id);
if ($('.form-control[name=countryID]').length) $('.form-control[name=countryID]').val(W.model.countries.top.id);
$('.action-buttons>.save-button').click();
break;
/*case 'cm_state':
var $selState = $('.form-control[name=stateID]>option');
$selState.map(function(i,opt){ console.info(opt.text); if (opt.text === val) opt.prop('selected','') });
break;*/
}
} catch(err) { console.error(err); }
};
var getTopCityName = function() {
return W.model.cities.objects[W.model.segments.topCityID].name;
};
//----------------------------------------------------------------------
var addStreetAndCityToRSel = function (segIds, caseSelection) {
var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
opNot = document.getElementById('cmOpNot').classList.contains('active'),
addConjunction = !!document.getElementById('outRSExpr').innerHTML.length, s;
switch (caseSelection ^ 0) {
case 'primaryStreet':
case 0:
if (segIds.primaryStreet.length !== 0) {
for (s = segIds.primaryStreet.length; s--;) {
if (addConjunction) {
if (opAndOr) {
document.getElementById('btnRSOr').click();
} else {
document.getElementById('btnRSAnd').click();
}
}
if (opNot) document.getElementById('btnRSNot').click();
//set to primary
document.getElementById('selRSAlttStreet').value = 0;
document.getElementById('selRSAltCity').value = 0;
document.getElementById('btnRSLBkt').click();
document.getElementById('inRSStreet').value = Waze.model.streets.objects[segIds.primaryStreet[s]].name;
document.getElementById('btnRSAddStreet').click();
//document.getElementById('btnRSAnd').click();
document.getElementById('inRSCity').value = Waze.model.cities.objects[Waze.model.streets.objects[segIds.primaryStreet[s]].cityID].name;
document.getElementById('btnRSAddCity').click();
document.getElementById('btnRSRBkt').click();
}
}
break;
case 'altStreets':
case 1:
if (segIds.altStreets.length !== 0) {
for (s = segIds.primaryStreet.length; s--;) {
if (addConjunction) {
if (opAndOr) {
document.getElementById('btnRSOr').click();
} else {
document.getElementById('btnRSAnd').click();
}
}
if (opNot) document.getElementById('btnRSNot').click();
//set to alt
document.getElementById('selRSAlttStreet').value = 1;
document.getElementById('selRSAltCity').value = 1;
document.getElementById('btnRSLBkt').click();
document.getElementById('inRSStreet').value = Waze.model.streets.objects[segIds.altStreets[s]].name;
document.getElementById('btnRSAddStreet').click();
//document.getElementById('btnRSAnd').click();
document.getElementById('inRSCity').value = Waze.model.cities.objects[Waze.model.streets.objects[segIds.altStreets[s]].cityID].name;
document.getElementById('btnRSAddCity').click();
document.getElementById('btnRSRBkt').click();
}
}
break;
case 'anyStreet':
case 2:
addStreetAndCityToRSel(segIds, 0); //primary
addStreetAndCityToRSel(segIds, 1); //alt
break;
}
};
var addStreetNameToRSel = function (segNames, inputFieldId, altSelId, altVal, addBtnId) {
var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
opNot = document.getElementById('cmOpNot').classList.contains('active'),
addConjunction = !!document.getElementById('outRSExpr').innerHTML.length;
for (var n = 0, nLength = segNames.length; n < nLength; n++) {
if (addConjunction) {
if (opAndOr) {
document.getElementById('btnRSOr').click();
} else {
document.getElementById('btnRSAnd').click();
}
}
if (opNot) document.getElementById('btnRSNot').click();
document.getElementById(inputFieldId).value = segNames[n];
document.getElementById(altSelId).value = altVal ^ 0;
document.getElementById(addBtnId).click();
addConjunction = true;
}
};
var addRoadTypeToRSel = function (ids, inputFieldId, addBtnId) {
var opAndOr = parseInt(document.getElementById('cmOpAddOr').value),
opNot = document.getElementById('cmOpNot').classList.contains('active'),
addConjunction = !!document.getElementById('outRSExpr').innerHTML.length;
document.getElementById('btnRSLBkt').click();
for (var n = 0, nLength = ids.length; n < nLength; n++) {
if (addConjunction) {
if (opAndOr) {
document.getElementById('btnRSOr').click();
} else {
document.getElementById('btnRSAnd').click();
}
}
if (opNot) document.getElementById('btnRSNot').click();
document.getElementById(inputFieldId).value = ids[n];
document.getElementById(addBtnId).click();
addConjunction = true;
}
document.getElementById('btnRSRBkt').click();
};
var copyToClipboard = function(id,str) {
var $hiddenText;
if (!document.getElementById('input_' + id)) {
$hiddenText = $('<input>');
$hiddenText.prop('id','input_' + id);
$hiddenText.css('position','fixed');
$hiddenText.css('top','-100px');
$hiddenText.css('left','-1000px');
$hiddenText.css('opacity',0);
$("body").append($hiddenText);
} else {
$hiddenText = $('#input_' + id);
}
$hiddenText.val(str).select();
document.execCommand("copy");
//$temp.remove();
};
var copyTo = function (e, opt, val) {
if (document.getElementById('cmPinMenu').value) e.stopPropagation();
if (document.getElementById('cmClipboard').value) {
copyToClipboard(opt,val);
if (document.getElementById('cmPinMenu').value) addPasteItems(opt);
} else {
try {
switch (opt) {
case 'cm_priSC':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetAndCityToRSel(val, 0);
document.getElementById('btnRSRBkt').click();
} else {
addStreetAndCityToRSel(val, 0);
}
break;
case 'cm_altSC':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetAndCityToRSel(val, 1);
document.getElementById('btnRSRBkt').click();
} else {
addStreetAndCityToRSel(val, 1);
}
break;
case 'cm_anySC':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetAndCityToRSel(val, 2);
document.getElementById('btnRSRBkt').click();
} else {
addStreetAndCityToRSel(val, 2);
}
break;
case 'cm_priS':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
document.getElementById('btnRSRBkt').click();
} else {
addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
}
break;
case 'cm_altS':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
document.getElementById('btnRSRBkt').click();
} else {
addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
}
break;
case 'cm_anyS':
if (document.getElementById('cmRoadType').classList.contains('active')) {
addRoadTypeToRSel(getUnique(val.roadType), 'selRSRoadType', 'btnRSAddRoadType');
document.getElementById('btnRSAnd').click();
document.getElementById('btnRSLBkt').click();
addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
document.getElementById('btnRSRBkt').click();
} else {
addStreetNameToRSel(getUnique(val.primaryStreet), 'inRSStreet', 'selRSAlttStreet', 0, 'btnRSAddStreet');
addStreetNameToRSel(getUnique(val.altStreets), 'inRSStreet', 'selRSAlttStreet', 1, 'btnRSAddStreet');
}
break;
case 'cm_ids':
document.getElementById('inRSSegId').value = val;
document.getElementById('btnRSAddSegId').classList.add('btn-info');
break;
case 'cm_primaryStreet':
document.getElementById('inRSStreet').value = val;
document.getElementById('selRSAlttStreet').value = 0;
document.getElementById('btnRSAddStreet').classList.add('btn-info');
break;
case 'cm_altStreets':
document.getElementById('inRSStreet').value = val;
document.getElementById('selRSAlttStreet').value = 1;
document.getElementById('btnRSAddStreet').classList.add('btn-info');
break;
case 'cm_altStreetsAND':
document.getElementById('inRSStreet').value = '';
break;
case 'cm_altStreetsOR':
document.getElementById('inRSStreet').value = '';
break;
case 'cm_primaryCity':
document.getElementById('inRSCity').value = val;
document.getElementById('selRSAltCity').value = 0;
document.getElementById('btnRSAddCity').classList.add('btn-info');
break;
case 'cm_altCities':
document.getElementById('inRSCity').value = val;
document.getElementById('selRSAltCity').value = 1;
document.getElementById('btnRSAddCity').classList.add('btn-info');
break;
case 'cm_state':
document.getElementById('inRSState').value = val;
document.getElementById('btnRSAddState').classList.add('btn-info');
break;
case 'cm_roadType':
document.getElementById('selRSRoadType').value = val;
document.getElementById('btnRSAddRoadType').classList.add('btn-info');
break;
case 'cm_updatedBy':
document.getElementById('inRSUpdtd').value = val;
document.getElementById('btnRSAddUpdtd').classList.add('btn-info');
break;
case 'cm_createdBy':
document.getElementById('inRSCrtd').value = val;
document.getElementById('btnRSAddCrtd').classList.add('btn-info');
break;
case 'cm_toConnections':
break;
}
} catch (err) {
console.error(err);
}
// swap panel from selection panel
try {
document.getElementById('user-info').style.display = 'block';
document.getElementById('edit-panel').style.display = 'none';
} catch (err) {
console.error(err);
}
// switch active tab-content
try {
document.querySelector('.tab-content>.active').classList.remove('active');
document.getElementById('sidepanel-roadselector').classList.add('active');
} catch (err) {}
// switch active nav-tab
try {
document.querySelector('#user-tabs li.active').classList.remove('active');
document.getElementById('tabRSel').classList.add('active');
} catch (err) {}
// switch to RSel editor tab
try {
document.getElementById('roadselector-tabs').children[1].classList.remove('active');
document.getElementById('roadselector-tabs').children[0].classList.add('active');
document.getElementById('roadselector-tab-content').children[1].classList.remove('active');
document.getElementById('roadselector-tab-content').children[0].classList.add('active');
} catch (err) { /* */ }
}
};
var getAutoAddToRSelCase = function (addType) {
var nameClass = ((document.getElementById('cm_pri').checked * document.getElementById('cm_pri').value) + (document.getElementById('cm_alt').checked * document.getElementById('cm_alt').value)) - 1;
switch (addType) {
case 'cm_S':
switch (nameClass) {
case 0: //primary
return 'cm_priS';
case 1: //alt
return 'cm_altS';
case 2: //any
return 'cm_anyS';
}
break;
case 'cm_SC': // cm_SC street and city
switch (nameClass) {
case 0: //primary
return 'cm_priSC';
case 1: //alt
return 'cm_altSC';
case 2: //any
return 'cm_anySC';
}
break;
}
};
var getSegmentProperties = function (selectedStuff) {
cmlog([1,1], 'getSegmentProperties()');
try {
/*var roadTypeOpts = document.querySelector('#segment-edit-general select[name="roadType"]'),
numRoadTypes = roadTypeOpts.options.length, r, roadTypes = {};
for (r=0; r < numRoadTypes; r++) {
roadTypes[roadTypeOpts[r].value] = roadTypeOpts[r].text;
}*/
var s, segments = selectedStuff.segments,
s_altStObjKeys, s_altSt, s_toConnObjKeys, a, numAlts, k, numKeys;
var s_ids = {
ids: {},
primaryStreet: {},
altStreets: {},
altCities: {},
roadType: {},
createdBy: {},
updatedBy: {},
toConnections: {},
primaryCity: {},
state: {},
country: {}
};
for (s = segments.length; s--;) {
if (segments[s].model.attributes.id)
s_ids.ids[segments[s].model.attributes.id] = null;
if (segments[s].model.attributes.primaryStreetID) {
s_ids.primaryStreet[segments[s].model.attributes.primaryStreetID] = null;
if (Waze.model.streets.objects[segments[s].model.attributes.primaryStreetID].cityID) {
s_ids.primaryCity[Waze.model.streets.objects[segments[s].model.attributes.primaryStreetID].cityID] = null;
if (Waze.model.cities.objects[Waze.model.streets.objects[segments[s].model.attributes.primaryStreetID].cityID].stateID)
s_ids.state[Waze.model.cities.objects[Waze.model.streets.objects[segments[s].model.attributes.primaryStreetID].cityID].stateID] = null;
s_ids.country[Waze.model.cities.objects[Waze.model.streets.objects[segments[s].model.attributes.primaryStreetID].cityID].countryID] = null;
}
}
s_ids.roadType[segments[s].model.attributes.roadType] = null;
s_ids.createdBy[segments[s].model.attributes.createdBy] = null;
if (segments[s].model.attributes.updatedBy)
s_ids.updatedBy[segments[s].model.attributes.updatedBy] = null;
s_altSt = segments[s].model.attributes.streetIDs;
numAlts = s_altSt.length;
for (a = 0; a < numAlts; a++) {
try {
s_ids.altStreets[s_altSt[a]] = null;
s_ids.altCities[Waze.model.streets.objects[s_altSt[a]].cityID] = null;
} catch(err) {}
}
s_toConnObjKeys = Object.keys(segments[s].model.attributes.toConnections);
numKeys = s_toConnObjKeys.length;
for (k = 0; k < numKeys; k++) {
try {
if (s_toConnObjKeys[k] !== '') {
s_ids.toConnections[s_toConnObjKeys[k]] = segments[s].model.attributes.toConnections[s_toConnObjKeys[k]];
}
} catch(err) {}
}
}
var seg_ids = {},
seg_names = {
ids: [],
primaryStreet: [],
altStreets: [],
altCities: [],
roadType: [],
createdBy: [],
updatedBy: [],
toConnections: [],
primaryCity: [],
state: [],
country: []
};
for (var idKey in s_ids) {
seg_ids[idKey] = Object.keys(s_ids[idKey]);
numKeys = seg_ids[idKey].length;
for (k = 0; k < numKeys; k++) {
try {
if (seg_ids[idKey][k] !== '') {
switch (idKey) {
case 'primaryStreet':
seg_names[idKey][k] = Waze.model.streets.objects[seg_ids[idKey][k]].name;
break;
case 'primaryCity':
seg_names[idKey][k] = Waze.model.cities.objects[seg_ids[idKey][k]].name;
break;
case 'altStreets':
seg_names[idKey][k] = Waze.model.streets.objects[seg_ids[idKey][k]].name;
break;
case 'altCities':
seg_names[idKey][k] = Waze.model.cities.objects[seg_ids[idKey][k]].name;
break;
case 'state':
seg_names[idKey][k] = Waze.model.states.objects[seg_ids[idKey][k]].name;
break;
case 'roadType':
seg_names[idKey][k] = roadTypes[String(seg_ids[idKey][k])];
break;
case 'createdBy':
seg_names[idKey][k] = Waze.model.users.objects[seg_ids[idKey][k]].userName;
break;
case 'updatedBy':
seg_names[idKey][k] = Waze.model.users.objects[seg_ids[idKey][k]].userName;
break;
}
}
} catch(err) {}
}
}
return {
ids: seg_ids,
names: seg_names
};
} catch (err) {
console.error(err);
}
};
var addHotkeyListener = function() {
cmlog([1,1], 'addHotkeyListener()');
window.addEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Adding global hotkey listener due to mouseenter');
};
var removeHotkeyListener = function() {
cmlog([1,1], 'removeHotkeyListener()');
window.removeEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Removing global hotkey listener due to mouseleave');
};
var closeContextMenu = function () {
cmlog([1,1], 'closeContextMenu()');
try {
// remove unnecessary hotkey listeners
window.removeEventListener('keydown', menuShortcutKeys, true);
document.getElementById('cmContextMenu').removeEventListener('mouseenter', addHotkeyListener, false);
document.getElementById('cmContextMenu').removeEventListener('mouseleave', removeHotkeyListener, false);
cmlog([2,2],'Closing menu, so removing all hotkey listeners');
// remove unnecessary close contextmenu listeners
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
Waze.selectionManager.events.unregister("selectionchanged", null, setupSegmentContextMenu);
// close the menu
document.getElementById('cmContextMenu').style.display = 'none';
SL.menuResetEvent = true;
} catch (err) {}
};
var addSpecialMenuListeners = function () {
cmlog([1,1], 'addSpecialMenuListeners()');
if (document.getElementById('cmPinMenu').value) {
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
} else {
window.addEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Adding just global hotkey listener via addSpecialMenuListeners()');
window.addEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').addEventListener('mouseenter', closeContextMenu, false);
}
};
var adjustContextMenubar = function(pos) {
if (pos === 1) {
document.getElementById('cmFooterCaret').classList.add('fa-angle-down');
document.getElementById('cmFooterCaret').classList.remove('fa-angle-up');
document.getElementById('cmFooter').classList.add('cm-top');
document.getElementById('cmFooter').classList.remove('cm-bottom');
document.getElementById('cmFooter').style.marginBottom = '-1px';
document.getElementById('cmContextMenu').insertBefore(document.getElementById('cmFooter'), document.getElementById('cmContextMenu').children[0]);
} else {
document.getElementById('cmFooterCaret').classList.add('fa-angle-up');
document.getElementById('cmFooterCaret').classList.remove('fa-angle-down');
document.getElementById('cmFooter').classList.remove('cm-top');
document.getElementById('cmFooter').classList.add('cm-bottom');
document.getElementById('cmFooter').style.marginBottom = '0';
document.getElementById('cmContextMenu').appendChild(document.getElementById('cmFooter'));
}
};
var hideMenuSection = function(evt, sectionName) {
var that;
if (evt) {
that = evt.target;
evt.stopPropagation();
} else if (sectionName) {
that = document.querySelector('.cm-menu-section[name=' + sectionName + ']>.cm-hide');
}
that.classList.toggle('fa-caret-down');
that.classList.toggle('fa-caret-up');
if (that.classList.contains('fa-caret-up')) { //hidden section
that.parentNode.classList.add('cm-hidden');
contextMenuSettings.hidden[that.parentNode.getAttribute('name')] = true;
} else { //revealed section
that.parentNode.classList.remove('cm-hidden');
contextMenuSettings.hidden[that.parentNode.getAttribute('name')] = false;
}
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
};
var resetContextMenu = function (contextMenuSettings) {
cmlog([1,1], 'resetContextMenu()');
var menuHTML;
if (menuResetEvent_RSel) document.getElementById('btnRSClear').click();
menuResetEvent_RSel = false;
try {
document.querySelector('#user-tabs a[href="#sidepanel-roadselector"]').parentNode.id = 'tabRSel';
} catch (err) {}
// <label for="cm_any" class="btn cm-rsel-options badge cm-badge-right active"><input id="cm_any" type="radio" name="cmOptions" value=2 style="opacity: 0" checked>any</label> //dl - background-color: rgba(177, 210, 220, 0.75);
if (contextMenuSettings.clipboard === 1) { //RSel
document.getElementById('cmContainer').innerHTML =
'<div id="cmRSelAutoAdd" class="cm-menu-section cm-rsel">' +
'<dl><dt>RSel Auto-Add Names</dt>' +
'<dd><div class="btn-group pull-left" data-toggle="buttons">' +
'<label for="cm_pri" class="btn cm-rsel-options cm-badge-left active"><input id="cm_pri" type="checkbox" value=1 checked> Primary</label>' +
'<label for="cm_alt" class="btn cm-rsel-options cm-badge-right active"><input id="cm_alt" type="checkbox" value=2 checked>Alternate </label>' +
'</div>' +
'<div class="pull-left btn-group" style="margin: 0px 2px">' +
'<button type="button" id="cmRoadType" class="btn cm-rsel-options active">Type</button>' +
'</div>' +
'<div class="btn-group pull-right">' +
'<button type="button" id="cmOpAddOr" class="btn cm-rsel-options cm-badge-left and" value="0" style="padding-right: 4px;">and</button>' +
'<button type="button" id="cmOpNot" class="btn cm-rsel-options cm-badge-right" style="padding-left: 4px;">!</button>' +
'</div></dd>' +
'<dd id="cm_SC">All <span id="cm_textSC">Primary/Alt. Street, City</span></dd>' +
'<dd id="cm_S">All <span id="cm_textS">Primary/Alt. Street</span></dd>' +
'</dl>' +
'</div>';
} else {
document.getElementById('cmContainer').innerHTML = '';
}
menuHTML = '<div class="cm-menu-header"><dl><dt id="cmMenuHeaderTitle">Copy To Clipboard</dt></dl></div>' +
'<div id="cmMenuNoContent" class="cm-menu-section" style="display: none;"><dd>No valid segment(s) selected</dd></div>' +
'<div id="cmMenuContent">' +
'<div id="cm_street" name="street" class="cm-menu-section">' +
'<span class="fa fa-caret-down cm-hide"></span><span class="fa fa-caret-up cm-hide"></span>' +
'<dl id="cm_primaryStreet"><dt>Street</dt></dl>' +
'<dl id="cm_altStreets"><dt>Alt street</dt></dl>' +
'</div>' +
'<div id="cm_city" name="city" class="cm-menu-section">' +
'<span class="fa fa-caret-down cm-hide"></span><span class="fa fa-caret-up cm-hide"></span>' +
'<dl id="cm_primaryCity"><dt>City</dt></dl>' +
'<dl id="cm_altCities"><dt>Alt city</dt></dl>' +
'</div>' +
'<div name="state" class="cm-menu-section">' +
'<span class="fa fa-caret-down cm-hide"></span><span class="fa fa-caret-up cm-hide"></span>' +
'<dl id="cm_state"><dt>State</dt></dl>' +
'</div>' +
'<div name="roadtype" class="cm-menu-section">' +
'<span class="fa fa-caret-down cm-hide"></span><span class="fa fa-caret-up cm-hide"></span>' +
'<dl id="cm_roadType"><dt>Road type</dt></dl>' +
'</div>' +
'<div name="by" class="cm-menu-section">' +
'<span class="fa fa-caret-down cm-hide"></span><span class="fa fa-caret-up cm-hide"></span>' +
'<dl id="cm_updatedBy"><dt>Updated by</dt></dl>' +
'<dl id="cm_createdBy"><dt>Created by</dt></dl>' +
'</div>' +
'<div name="id" class="cm-menu-section">' +
'<dl><dd id="cm_ids">Segment IDs</dd></dl>' +
'</div></div>';
for (var h in contextMenuSettings.hidden) {
if (contextMenuSettings.hidden[h]) //hideMenuSection(null, h);
menuHTML = menuHTML.replace(new RegExp('(name="' + h + '" class=")','m'),'$1cm-hidden ');
}
document.getElementById('cmContainer').innerHTML += menuHTML;
$('.cm-hide').click(hideMenuSection);
// if menu is not pinned
if (!document.getElementById('cmPinMenu').value) {
setTimeout(addSpecialMenuListeners, 250);
}
adjustContextMenubar(contextMenuSettings.position);
};
var hidePasteMenu = function(bit) {
if (bit === undefined) bit = !document.getElementById('cmClipboard').value;
if ($('.cm-paste').length) {
$('.cm-paste').each(function(i, node) {
if (bit) node.style.display = 'none';
else node.style.display = '';
});
}
};
var populateCopyMenu = function (segInfo, contextMenuSettings) {
cmlog([1,1], 'populateCopyMenu()');
document.getElementById('cmMenuNoContent').style.display = 'none';
document.getElementById('cmMenuContent').style.display = 'block';
try {
resetContextMenu(contextMenuSettings);
var updateNames = Object.keys(segInfo.ids),
numNames = updateNames.length,
n, selOption, emptyArr, s_names = {},
s_ids = {}, clipboard, pasteOption, sectionElement;
for (n = numNames; n--;) {
sectionElement = document.getElementById('cm_' + updateNames[n]);
if (sectionElement &&
segInfo.ids[updateNames[n]] &&
segInfo.ids[updateNames[n]].length) {
if (updateNames[n] !== 'ids') {
emptyArr = 0;
s_names[updateNames[n]] = getUnique(segInfo.names[updateNames[n]]);
s_ids[updateNames[n]] = getUnique(segInfo.ids[updateNames[n]]);
for (var a = 0, aLength = s_ids[updateNames[n]].length; a < aLength; a++) {
try {
selOption = document.createElement('dd');
if (s_names[updateNames[n]][a]) {
if (s_names[updateNames[n]][a] === '') { //no city or no street
if (/city/i.test(updateNames[n])) {
selOption.innerHTML = 'No City';
} else if (/street/i.test(updateNames[n])) {
selOption.innerHTML = 'No Street';
}
//selOption.name = '';
} else { //add the property value to the menu
selOption.innerHTML = s_names[updateNames[n]][a];
//selOption.name = s_names[updateNames[n]][a];
}
sectionElement.appendChild(selOption);
switch (updateNames[n]) {
case 'roadType':
selOption.name = s_ids[updateNames[n]][a];
if (document.getElementById('cmClipboard').value) selOption.name = s_names[updateNames[n]][a];
selOption.onclick = function (e) {
//if (document.getElementById('cmPinMenu').value) e.stopPropagation();
copyTo(e, this.parentNode.id, this.name);
};
break;
default:
selOption.name = s_names[updateNames[n]][a];
selOption.onclick = function (e) {
//if (document.getElementById('cmPinMenu').value) e.stopPropagation();
copyTo(e, this.parentNode.id, this.name);
};
}
} else {
emptyArr++;
}
} catch(err) { console.error(err); }
}
// Check if something has been copied into clipboard for pasting...
if (document.getElementById('cmClipboard').value) addPasteItems('cm_' + updateNames[n]);
// Hide section if nothing to copy
if (emptyArr === aLength && !$('#input_cm_' + updateNames[n]).length) {
sectionElement.style.display = "none";
//sectionElement.parentNode.children[0].style.display = "none";
} else if ($('#input_cm_' + updateNames[n]).length) { //show if something to paste
selOption = document.createElement('dd');
selOption.innerHTML = ' ';
sectionElement.appendChild(selOption);
}
} else { // Segment IDs
selOption = document.getElementById('cm_ids');
selOption.name = segInfo.ids[updateNames[n]].join(',');
selOption.onclick = function (e) {
//if (document.getElementById('cmPinMenu').value) e.stopPropagation();
copyTo(e, this.id, this.name);
};
}
//--------------------------------------------
} else if (sectionElement && !$('#input_cm_' + updateNames[n]).length) { // Hide section if nothing to copy
//sectionElement.parentNode.style.display = "none";
sectionElement.style.display = "none";
sectionElement.parentNode.children[0].style.display = "none"; //caret-down
sectionElement.parentNode.children[1].style.display = "none"; //caret-up
} else if (sectionElement && $('#input_cm_' + updateNames[n]).length) { //show if something to paste
selOption = document.createElement('dd');
if (/city/i.test(updateNames[n])) {
selOption.innerHTML = 'No City';
} else if (/street/i.test(updateNames[n])) {
selOption.innerHTML = 'No Street';
} /*else {
selOption.innerHTML = ' ';
}*/
if (selOption.innerHTML.length) {
selOption.name = '';
sectionElement.appendChild(selOption);
selOption.onclick = function (e) {
//if (document.getElementById('cmPinMenu').value) e.stopPropagation();
copyTo(e, this.parentNode.id, this.name);
};
sectionElement.appendChild(selOption);
}
}
}
// Hide sections if nothing to copy
if (!s_names.primaryStreet.length && !s_names.altStreets.length && !$('#input_cm_primaryStreet').length) {
document.getElementById('cm_primaryStreet').parentNode.style.display = 'none';
}
if (!s_names.primaryCity.length && !s_names.altCities.length && !$('#input_cm_primaryCity').length) {
document.getElementById('cm_primaryCity').parentNode.style.display = 'none';
}
if (!s_names.state.length) document.getElementById('cm_state').parentNode.style.display = 'none';
var numSegments = Waze.selectionManager.selectionCountByType.segment;
if (!numSegments) numSegments = '0 Segment IDs';
else if (numSegments === 1) numSegments = '1 Segment ID';
else numSegments = numSegments + ' Segment IDs';
document.getElementById('cm_ids').innerHTML = numSegments;
//=================================================================================
// RSEL-specific menu items
//=================================================================================
if (document.getElementById('cmRSel').value) {
document.getElementById('cmMenuHeaderTitle').innerHTML = 'Send To Road Selector';
var copyToRSelAndSelect = document.createElement('dd');
copyToRSelAndSelect.id = 'cm_SCgo';
copyToRSelAndSelect.zIndex = 1;
copyToRSelAndSelect.className = 'fa fa-fast-forward pull-right cm-rsel-goselect';
document.getElementById('cm_SC').parentNode.insertBefore(copyToRSelAndSelect, document.getElementById('cm_SC'));
var copyToRSelAndSelect2 = copyToRSelAndSelect.cloneNode();
copyToRSelAndSelect2.id = 'cm_Sgo';
copyToRSelAndSelect.zIndex = 1;
document.getElementById('cm_S').parentNode.insertBefore(copyToRSelAndSelect2, document.getElementById('cm_S'));
document.getElementById('cmRSelAutoAdd').style.display = 'block';
//name options
document.getElementById('cm_pri').parentNode.addEventListener('click', function (e) {
e.stopPropagation();
var numBtnDown = this.parentNode.getElementsByClassName('active').length;
if (this.children[0].checked) { //currently checked... decide whether to uncheck
this.classList.remove('active');
this.children[0].checked = false;
if (numBtnDown === 0) {
document.getElementById('cm_alt').parentNode.classList.add('active');
document.getElementById('cm_alt').checked = true;
}
document.getElementById('cm_textSC').innerHTML = 'Alt. Street, City';
document.getElementById('cm_textS').innerHTML = 'Alt. Street';
} else { //unchecked
this.classList.add('active');
this.children[0].checked = true;
document.getElementById('cm_textSC').innerHTML = 'Primary/Alt. Street, City';
document.getElementById('cm_textS').innerHTML = 'Primary/Alt. Street';
}
}, false);
document.getElementById('cm_alt').parentNode.addEventListener('click', function (e) {
e.stopPropagation();
var numBtnDown = this.parentNode.getElementsByClassName('active').length;
if (this.children[0].checked) { //currently checked... decide whether to uncheck
this.classList.remove('active');
this.children[0].checked = false;
if (numBtnDown === 0) {
document.getElementById('cm_pri').parentNode.classList.add('active');
document.getElementById('cm_pri').checked = true;
}
document.getElementById('cm_textSC').innerHTML = 'Primary Street, City';
document.getElementById('cm_textS').innerHTML = 'Primary Street';
} else { //unchecked
this.classList.add('active');
this.children[0].checked = true;
document.getElementById('cm_textSC').innerHTML = 'Primary/Alt. Street, City';
document.getElementById('cm_textS').innerHTML = 'Primary/Alt. Street';
}
}, false);
//road type
document.getElementById('cmRoadType').addEventListener('click', function (e) {
e.stopPropagation();
if (document.getElementById('cmRoadType').classList.contains('active')) {
document.getElementById('cmRoadType').classList.remove('active');
} else {
document.getElementById('cmRoadType').classList.add('active');
}
}, false);
//operations
document.getElementById('cmOpAddOr').addEventListener('click', function (e) {
e.stopPropagation();
var opToggleLabel = ['and', 'or'],
newValue = this.value ^ 1;
this.innerHTML = opToggleLabel[newValue];
this.value = newValue;
//console.info(this.value);
}, false);
document.getElementById('cmOpNot').addEventListener('click', function (e) {
e.stopPropagation();
if (document.getElementById('cmOpNot').classList.contains('active')) {
document.getElementById('cmOpNot').classList.remove('active');
} else {
document.getElementById('cmOpNot').classList.add('active');
}
}, false);
//menu selections
document.getElementById('cm_SC').addEventListener('click', function (e) {
copyTo(e, getAutoAddToRSelCase('cm_SC'), segInfo.ids);
}, false);
document.getElementById('cm_S').addEventListener('click', function (e) {
copyTo(e, getAutoAddToRSelCase('cm_S'), segInfo.names);
}, false);
document.getElementById('cm_SCgo').addEventListener('click', function (e) {
menuResetEvent_RSel = true;
copyTo(e, getAutoAddToRSelCase('cm_SC'), segInfo.ids);
document.getElementById('btnRSSelect').click();
}, false);
document.getElementById('cm_Sgo').addEventListener('click', function (e) {
menuResetEvent_RSel = true;
copyTo(e, getAutoAddToRSelCase('cm_S'), segInfo.names);
document.getElementById('btnRSSelect').click();
}, false);
}
} catch (err) {
cmlog([1,1], err);
//console.error(err);
}
};
//===============================================================================================
SL.checkCountry = function () {
cmlog([1,1], 'SL.checkCountry()');
//for (i=1; i<17; i++) {kph=Math.round(i*5*SL.imperial.mph2kph); mph=Math.round(kph*SL.imperial.kph2mph); console.info('kph:',kph,'---','mph:',mph)}
if (!contextMenuSettings.countries) contextMenuSettings.countries = [];
var savedNumCountries = contextMenuSettings.countries.length,
currentNumCountries, currentCountries, convertUnits = false, isImperialCountry = false;
try {
currentCountries = [Waze.model.countries.top.abbr];
currentNumCountries = 1;
} catch (err) {
console.warning('WMECM:', 'Could not find W.model.countries.top. Trying to use W.model.countries.objects instead.');
try {
currentCountries = Object.keys(Waze.model.countries.objects);
currentNumCountries = currentCountries.length;
} catch (err) {
console.warning('WMECM:', 'WME objects might have been changed by Waze. This could be a problem and should be examined.');
currentCountries = false;
currentNumCountries = 0;
}
}
var matchCount = 0;
for (var c = 0; c < currentNumCountries; c++) {
for (var s = 0; s < savedNumCountries; s++) {
if (currentCountries[c] === contextMenuSettings.countries[s]) matchCount++;
}
}
for (var ic = 0, icLength = SL.imperial.mphCountries.length; ic < icLength; ic++) {
if (currentCountries[0] === SL.imperial.mphCountries[ic]) {
isImperialCountry = true;
break;
}
}
if (isImperialCountry && !Waze.prefs.attributes.isImperial) convertUnits = 1; //convert metric --> imperial
else if (!isImperialCountry && Waze.prefs.attributes.isImperial) convertUnits = 2; //convert imperial --> metric
SL.imperial.useMPH = isImperialCountry;
SL.imperial.convertUnits = convertUnits;
SL.currentCountry = currentCountries[0];
if (matchCount !== currentNumCountries) {
contextMenuSettings.countries = currentCountries;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
SL.forceBuildNewMenu = true;
return true; //saved for later for implementing a check without having to refresh browser
} else {
return false;
}
};
SL.highlightSpeedSigns = function () {
cmlog([1,1], 'SL.highlightSpeedSigns()');
//$('#signsholder_cm>div').removeAttr('style'); //reset styles
$('#signsholder_cm>div:not(#btnCMClearSLs)').removeAttr('class'); //reset classes
//if (SL.imperial.convertUnits === null) SL.checkCountry();
// Highlight the current speed limit
var fwdSL = document.querySelector('input[name="fwdMaxSpeed"]'), fwdSpeedVal,
revSL = document.querySelector('input[name="revMaxSpeed"]'), revSpeedVal,
numSegments = Waze.selectionManager.selectionCountByType.segment,
fwdSLMenu = document.querySelector('input[name="fwdMaxSpeed_cm'),
revSLMenu = document.querySelector('input[name="revMaxSpeed_cm'),
unverFwdChkBox = document.getElementById('fwdMaxSpeedUnverifiedCheckbox'),
unverRevChkBox = document.getElementById('revMaxSpeedUnverifiedCheckbox'),
signFwd, signRev;
if (fwdSL !== null) fwdSpeedVal = fwdSL.valueAsNumber;
if (revSL !== null) revSpeedVal = revSL.valueAsNumber;
if ((fwdSpeedVal+revSpeedVal) === 0) {
return;
} else if ((revSLMenu && revSLMenu.parentNode.style.display === 'none') || revSpeedVal===0) {
revSpeedVal = false;
} else if ((fwdSLMenu && fwdSLMenu.parentNode.style.display === 'none') || fwdSpeedVal===0) {
fwdSpeedVal = false;
}
if (SL.imperial.convertUnits === 1) {
if (fwdSpeedVal) fwdSpeedVal = Math.round(fwdSpeedVal * SL.imperial.kph2mph);
if (revSpeedVal) revSpeedVal = Math.round(revSpeedVal * SL.imperial.kph2mph);
} else if (SL.imperial.convertUnits === 2) {
if (fwdSpeedVal) fwdSpeedVal = Math.round(fwdSpeedVal * SL.imperial.mph2kph);
if (revSpeedVal) revSpeedVal = Math.round(revSpeedVal * SL.imperial.mph2kph);
}
signFwd = document.querySelector('#signsholder_cm>div[id="sign' + fwdSpeedVal + '"]');
signRev = document.querySelector('#signsholder_cm>div[id="sign' + revSpeedVal + '"]');
if ((fwdSpeedVal && revSpeedVal) && (fwdSpeedVal === revSpeedVal)) {
if ((unverFwdChkBox === null && unverRevChkBox === null) || // if both have been verified
(unverFwdChkBox && unverRevChkBox && unverFwdChkBox.checked === true && unverRevChkBox.checked === true)) {
if (signFwd) signFwd.className ='cm-sl-verified cm-both';
} else if ((unverFwdChkBox === null || unverFwdChkBox.checked === true) ||
(unverRevChkBox === null || unverRevChkBox.checked === true)) { // only one has been verified
if (signFwd) signFwd.className ='cm-sl-unverified cm-one';
} else if (unverFwdChkBox.checked === false && unverRevChkBox.checked === false) { // neither have been verified
if (signFwd) signFwd.className ='cm-sl-unverified cm-both';
}
} else if ((fwdSpeedVal && revSpeedVal) && (fwdSpeedVal !== revSpeedVal)) {
if ((unverFwdChkBox === null && unverRevChkBox === null) || // if both have been verified -- no checkboxes
(unverFwdChkBox && unverRevChkBox && unverFwdChkBox.checked === true && unverRevChkBox.checked === true)) { // or both checked
if (signFwd) signFwd.className ='cm-sl-verified cm-a';
if (signRev) signRev.className ='cm-sl-verified cm-b';
} else if (unverFwdChkBox === null || unverFwdChkBox.checked === true) { //fwdSpeedVal checked or no checkbox
if (signFwd) signFwd.className ='cm-sl-verified cm-a';
if (signRev)signRev.className ='cm-sl-unverified cm-b';
} else if (unverRevChkBox === null || unverRevChkBox.checked === true) { //revSpeedVal checked or no checkbox
if (signFwd) signFwd.className ='cm-sl-unverified cm-a';
if (signRev)signRev.className ='cm-sl-verified cm-b';
} else if (unverFwdChkBox.checked === false && unverRevChkBox.checked === false) { //both unchecked
if (signFwd) signFwd.className ='cm-sl-unverified cm-a';
if (signRev)signRev.className ='cm-sl-unverified cm-b';
}
} else if (fwdSpeedVal && !revSpeedVal) { // no reverse speed has been inputted
if (document.querySelector('input[name="revMaxSpeed"]') === null) { // if revSpeedVal input does not exist bc this is a oneway road
if (unverFwdChkBox === null || unverFwdChkBox.checked === true) { // if fwdSpeedVal has been verified
if (signFwd) signFwd.className ='cm-sl-verified';
} else if (unverFwdChkBox.checked === false) { //unverified speed on oneway road
if (signFwd) signFwd.className ='cm-sl-unverified';
}
} else { //revSpeedVal input box does exist but is empty
if (unverFwdChkBox === null || unverFwdChkBox.checked === true) { // if fwdSpeedVal has been verified, then draw green box
if (signFwd) signFwd.className ='cm-sl-verified cm-a';
} else if (unverFwdChkBox.checked === false) { //unverified speed on oneway road
if (signFwd) signFwd.className ='cm-sl-unverified cm-a';
}
}
} else if (revSpeedVal && !fwdSpeedVal) {
if (document.querySelector('input[name="fwdMaxSpeed"]') === null) { // if fwdSpeedVal input does not exist bc this is a oneway road
if (unverRevChkBox === null || unverRevChkBox.checked === true) { //revSpeedVal has been verified
if (signRev)signRev.className ='cm-sl-verified';
} else if (unverRevChkBox.checked === false) { //unverified speed on oneway road
if (signRev)signRev.className ='cm-sl-unverified';
}
} else { //fwdSpeedVal does exist, but has not been inputted
if (unverRevChkBox === null || unverRevChkBox.checked === true) { //revSpeedVal has been verified
signRev.className ='cm-sl-verified cm-b';
} else if (unverRevChkBox.checked === false) { //unverified speed on oneway road
if (signRev) signRev.className ='cm-sl-unverified cm-b';
}
}
}
if (numSegments > 1) $('#signsholder_cm>div.cm-sl-verified').addClass('cm-sl-multisegs');
};
SL.getSpeedLimits = function() {
var origSignsEl = document.querySelectorAll('#signsholder>div[id^="sign"]'),
signsEls = document.querySelectorAll('#signsholder_cm>div[id^="sign"]'),
speedLimits = [];
if (origSignsEl.length !== 0) signsEls = origSignsEl;
for (var s = 0, nSigns = signsEls.length; s < nSigns; s++) {
speedLimits.push(signsEls[s].children[0].innerHTML);
}
return speedLimits;
};
SL.createSpeedSigns = function() {
if (!SL.currentCountry) SL.checkCountry();
var signsHTML = '<div id="btnCMClearSLs" class="fa fa-ban"><div>0</div></div>',
signsCSSEl, signsCSS, speedLimits, speedSignSettings,
country = SL.currentCountry,
signsHolderEl = document.getElementById('signsholder_cm');
if (document.getElementById('cmSignsWait') !== null ) document.getElementById('cmSignsWait').remove();
if (SL.speedhelperIsPresent === true || document.getElementById('cmSpeedhelperCSS') !== null) {
if (document.getElementById('cmSpeedSignsCSS')) {
document.getElementById('cmSpeedSignsCSS').remove();
if (document.getElementById('signsholder_cm') !== null) document.getElementById('signsholder_cm').className = '';
}
if (contextMenuSettings.speedhelper && contextMenuSettings.speedhelper[country] && contextMenuSettings.speedhelper[country].speeds) {
speedLimits = contextMenuSettings.speedhelper[country].speeds;
} else {
speedLimits = SL.getSpeedLimits();
contextMenuSettings.speedhelper[country] = {speeds: speedLimits};
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
}
} else {
if (contextMenuSettings.speedSigns[country] !== undefined && contextMenuSettings.speedSigns[country].speeds !== undefined && contextMenuSettings.speedSigns[country].speeds.length !== 0) {
if (contextMenuSettings.speedSigns[country].signShape === undefined)
contextMenuSettings.speedSigns[country].signShape = contextMenuSettings.speedSigns.default.signShape;
if (contextMenuSettings.speedSigns[country].signBorderColor === undefined)
contextMenuSettings.speedSigns[country].signBorderColor = contextMenuSettings.speedSigns.default.signBorderColor;
speedSignSettings = contextMenuSettings.speedSigns[country];
speedLimits = speedSignSettings.speeds;
} else {
speedSignSettings = contextMenuSettings.speedSigns.default;
speedLimits = speedSignSettings.speeds;
if (SL.imperial.useMPH) {
speedLimits = speedLimits.slice(0,15);
} else {
speedLimits = speedLimits.filter((a,i) => (Number.isInteger(a/10)) ? i : false);
}
contextMenuSettings.speedSigns[country] = { speeds: speedLimits,
signShape: speedSignSettings.signShape,
signBorderColor: speedSignSettings.signBorderColor};
}
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
if (signsHolderEl === null) {
signsHolderEl = document.createElement('div');
signsHolderEl.id = 'signsholder_cm';
document.getElementById('signsContainer').appendChild(signsHolderEl);
}
signsCSSEl = document.getElementById('cmSpeedSignsCSS');
if (signsCSSEl !== null) signsCSSEl.remove();
signsCSSEl = document.createElement('style');
signsCSSEl.type = 'text/css';
signsCSSEl.id = 'cmSpeedSignsCSS';
signsCSS =
'#signsholder_cm>div[id^="sign"] { cursor: pointer; float: left; border-color: ' + speedSignSettings.signBorderColor + '; border-style: solid; background-color: #F5FCFF; position: relative; }\n' +
'#signsholder_cm.cm-sl-circ>div[id^="sign"] { line-height: 1.8; letter-spacing: -0.9px; border-width: 3px; width: 30px; height: 30px; margin: 0px 0px 4px 3px; border-radius: 50%; font-family: helvetica, arial, "open sans"; }\n' +
'#signsholder_cm.cm-sl-sqr>div[id^="sign"] { line-height: 1.9; letter-spacing: 0.5px; border-width: 2px; width: 30px; height: 30px; margin: 0px 1px 4px 2px; border-radius: 3px; opacity: 0.95; }\n' +
'#signsholder_cm.cm-sl-circ>#btnCMClearSLs { border: 3px solid transparent; width: 30px; height: 30px; margin: -4px 0px 4px 3px; }\n' +
'#signsholder_cm.cm-sl-sqr>#btnCMClearSLs { border: 2px solid transparent; width: 30px; height: 30px; margin: -3px 1px 4px 2px; }\n' +
'#signsholder_cm>div>* { opacity: 1; position: relative; text-align: center; vertical-align: middle; color: #000; font-weight: bold; font-size: 14px; margin-left: -1px; }\n' +
'#signsholder_cm.cm-sl-sqr>div>* { margin-left: 0; padding-top: 1px; }\n';
signsCSSEl.innerHTML = signsCSS;
document.body.appendChild(signsCSSEl);
switch (speedSignSettings.signShape) {
case 'Square':
signsHolderEl.classList.remove('cm-sl-circ');
signsHolderEl.classList.add('cm-sl-sqr');
break;
case 'Circle':
signsHolderEl.classList.add('cm-sl-circ');
signsHolderEl.classList.remove('cm-sl-sqr');
break;
}
}
for (var sl=0, slLength = speedLimits.length; sl < slLength; sl++) {
signsHTML += '<div id="sign' + speedLimits[sl] + '"><div>' + speedLimits[sl] + '</div></div>';
}
signsHolderEl.innerHTML = signsHTML;
SL.signsContainerHTML = document.getElementById('signsContainer').innerHTML;
};
SL.removeSpeedSign = function(evt) {
var speedVal = evt.target.firstElementChild.innerHTML,
speedLimits = SL.getSpeedLimits();
if (/\d+/.test(speedVal)) {
speedLimits = speedLimits.join().replace(speedVal,'').match(/\d+/g);
if (SL.speedhelperIsPresent === false)
contextMenuSettings.speedSigns[SL.currentCountry].speeds = speedLimits;
else contextMenuSettings.speedhelper[SL.currentCountry].speeds = speedLimits;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
evt.target.remove();
SL.signsContainerHTML = document.getElementById('signsContainer').innerHTML;
}
};
SL.closeSpeedSignsEditor = function () {
//document.querySelector('#cmMenuHeaderTitle>.fa-pencil').onclick = SL.editSpeedSigns;
document.getElementById('cmContextMenu').addEventListener('mouseenter', addHotkeyListener, false);
window.addEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Removed focus from speed limit edit, so adding global hotkey listener again');
if (!document.getElementById('cmPinMenu').value) {
cmlog([2,2], 'Adding event listners to allow menu to close');
addSpecialMenuListeners();
}
document.getElementById('cmMenuSLEdit').remove();
document.getElementById('btnCMSLEditDone').previousElementSibling.style.color = '';
document.getElementById('btnCMSLEditDone').remove();
};
SL.saveSpeedSignEdits = function(e) {
e.stopPropagation();
var editedSpeedLimits = document.querySelector('#cmMenuSLEdit textarea').value,
country = SL.currentCountry;
if (editedSpeedLimits.length !== 0) {
editedSpeedLimits = editedSpeedLimits.match(/\d+/g)
contextMenuSettings.speedSigns[country] = {};
if (SL.speedhelperIsPresent === false) {
contextMenuSettings.speedSigns[country].speeds = editedSpeedLimits;
contextMenuSettings.speedSigns[country].signShape = document.querySelector('#cmMenuSLEdit select').value;
contextMenuSettings.speedSigns[country].signBorderColor = document.querySelector('#cmMenuSLEdit input[name="signBorderColor"]').value
} else { contextMenuSettings.speedhelper[country] = {speeds: editedSpeedLimits}; }
}
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
SL.createSpeedSigns();
SL.addListenersToSigns(false);
//document.querySelector('#cmMenuHeaderTitle>.fa-pencil').onclick = SL.editSpeedSigns;
setTimeout(SL.closeSpeedSignsEditor,150);
};
SL.editSpeedSigns = function(evt) {
evt.stopPropagation();
if (document.getElementById('cmMenuSLEdit') !== null) {
SL.closeSpeedSignsEditor();
} else {
try {
document.getElementById('cmContextMenu').removeEventListener('mouseenter', addHotkeyListener, false);
window.removeEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'removing global hotkey listener');
if (!document.getElementById('cmPinMenu').value) {
cmlog([2,2],'Preventing menu from closing by removing event listeners');
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
}
evt.target.style.color = '#FFF';
SL.checkCountry();
var speedLimits,
editSLEl = document.createElement('div'),
country = SL.currentCountry;
editSLEl.id = 'cmMenuSLEdit';
editSLEl.className = 'cm-menu-section';
editSLEl.style.display = 'block';
editSLEl.style.padding = '5px 10px';
editSLEl.style.position = 'relative';
editSLEl.style.color = '#234350';
editSLEl.style.fontSize = '10px';
editSLEl.style.textTransform = 'uppercase';
editSLEl.style.letterSpacing = '-0.3px';
editSLEl.style.fontWeight = 'bold';
if (SL.speedhelperIsPresent !== true && document.getElementById('cmSpeedhelperCSS') === null) {
if (contextMenuSettings.speedSigns[country] !== undefined && contextMenuSettings.speedSigns[country].speeds !== undefined && contextMenuSettings.speedSigns[country].speeds.length !== 0) {
speedSignSettings = contextMenuSettings.speedSigns[country];
speedLimits = speedSignSettings.speeds.join(' ');
} else {
speedSignSettings = contextMenuSettings.speedSigns.default;
speedLimits = SL.getSpeedLimits().join(' ');
}
editSLEl.innerHTML = '<div style="display: flex; position: relative">' +
'<p style="min-width: 50%"> Shape <select style="margin: 3px 0 0; padding: 0px 3px; border-radius: 5px; height: 20px; width: 70px; display: block;"><option selected>Circle</option><option>Square</option></select></p>' +
'<p style="min-width: 30%;"> Border <input type="color" value="' + speedSignSettings.signBorderColor + '" name="signBorderColor" list="signBorderColorList" style="margin: 3px 0 0; display: block; border-radius: 5px; padding: 3px 2px; height: 20px; border-color: transparent; width: 50px; background-color: rgba(255, 255, 255, 0.3);"></input>' +
'<datalist id="signBorderColorList"><option>#34444B</option><option>#DC0F00</option><option>#03A9F4</option><option>#416B7C</option><option>#888888</option></datalist></p></div>' +
'<p> Add/Remove Speed Limits<textarea class="form-control" style="max-width: 100%; height: auto; margin: 3px 0px 0px; word-spacing: 2px; font-weight: 600; padding: 2px 8px;">' + speedLimits + '</textarea></p>';
document.getElementById('cmMenuContent').insertBefore(editSLEl, document.getElementById('cmSpeedLimit'));
document.querySelector('#cmMenuSLEdit select').value = speedSignSettings.signShape;
} else {
if (contextMenuSettings.speedhelper[country] !== undefined) speedLimits = contextMenuSettings.speedhelper[country].speeds.join(' ');
else speedLimits = SL.getSpeedLimits().join(' ');
editSLEl.innerHTML =
'<p> Add/Remove Speed Limits<textarea class="form-control" style="max-width: 100%; height: auto; margin: 3px 0px 0px; word-spacing: 2px; font-weight: 600; padding: 2px 8px;">' + speedLimits + '</textarea></p>';
document.getElementById('cmMenuContent').insertBefore(editSLEl, document.getElementById('cmSpeedLimit'));
}
document.getElementById('cmMenuHeaderTitle').innerHTML += '<span id="btnCMSLEditDone" style="float: right; padding-right: 8px; margin-right: 2px; display: inline-flex; color: greenyellow; border-right: 1px solid #D8E9EF; cursor: pointer;"><i class="fa fa-check fa-fw"></i> DONE</span>';
document.getElementById('btnCMSLEditDone').onclick = SL.saveSpeedSignEdits;
document.querySelector('#cmMenuHeaderTitle>.fa-pencil').onclick = SL.editSpeedSigns;
} catch(err) { console.error(err); }
}
};
//------------------------------------------------------------------------------
SL.reduceSpeedhelperOverhead = function () {
cmlog([1,1], 'SL.reduceSpeedhelperOverhead()');
if (document.getElementById('cmSpeedhelperCSS')) document.getElementById('cmSpeedhelperCSS').remove();
if (document.getElementById('cmSpeedSignsCSS')) {
document.getElementById('cmSpeedSignsCSS').remove();
if (document.getElementById('signsholder_cm') !== null) document.getElementById('signsholder_cm').className = '';
}
var speedhelperCSSEl = document.createElement('style');
speedhelperCSSEl.type = 'text/css';
speedhelperCSSEl.id = 'cmSpeedhelperCSS';
speedhelperCSSEl.innerHTML =
'#signsholder_cm>div[id^="sign"], #btnCMClearSLs {margin-bottom: 1px; ' + document.getElementById('signsholder').children[0].getAttribute('style') + '}\n' +
'#signsholder_cm>div[id^="sign"]>* {' + document.querySelector('#signsholder>div[id^="sign"]>*').getAttribute('style') + '}\n';
document.body.appendChild(speedhelperCSSEl);
$('#signsholder_cm>div[id^="sign"]:not([id="signsError"]').removeAttr('style');
$('#signsholder_cm>div[id^="sign"]>div').removeAttr('style');
SL.signsContainerHTML = document.getElementById('signsContainer').innerHTML;
//return document.getElementById('cmMenuContent').innerHTML;
};
//===============================================================================
SL.checkUnits = function(speedVal) {
speedVal = Number(speedVal);
if (SL.imperial.convertUnits === 1) {
return Math.round(speedVal * SL.imperial.mph2kph);
} else if (SL.imperial.convertUnits === 2) {
return Math.round(speedVal * SL.imperial.kph2mph);
} else {
return speedVal;
}
};
SL.addSpeedSignAB = function(speedVal) {
var fwdSLMenu = document.querySelector('input[name="fwdMaxSpeed_cm'),
fwdSL = document.querySelector('input[name="fwdMaxSpeed"]'),
fwdChkBox = document.getElementById('fwdMaxSpeedUnverifiedCheckbox'),
prevFwdSpeedVal = fwdSLMenu.value,
numSegsSelected = Waze.selectionManager.selectionCountByType.segment,
pauseTime = (numSegsSelected > 10) ? (50+numSegsSelected) : 0;
cmlog([5,3],speedVal);
if (fwdSL.disabled === false) {
document.getElementById('cmWaitCover').style.display = 'block';
speedVal = SL.checkUnits(speedVal);
requestAnimationFrame(function(){
var fwdChkBoxMenu = document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm');
if (fwdChkBoxMenu !== null) fwdChkBoxMenu.checked = true;
fwdSLMenu.value = speedVal;
});
setTimeout(function(){
if (fwdChkBox !== null && speedVal === prevFwdSpeedVal) {
fwdChkBox.checked = true;
fwdChkBox.dispatchEvent(changeEvent);
} else if (fwdSL !== null) {
fwdSL.value = speedVal;
fwdSL.dispatchEvent(changeEvent);
//$(fwdSL).val(speedVal).change();
if (fwdChkBox !== null) setTimeout(function(){fwdChkBox.checked = true;},20);
}
if (!document.getElementById('cmPinMenu').value) setTimeout(closeContextMenu, 150);
else setTimeout(SL.highlightSpeedSigns,50);
document.getElementById('cmWaitCover').style.display = 'none';
},pauseTime);
}
};
SL.addSpeedSignBA = function(speedVal) {
var revSLMenu = document.querySelector('input[name="revMaxSpeed_cm'),
revSL = document.querySelector('input[name="revMaxSpeed"]'),
revChkBox = document.getElementById('revMaxSpeedUnverifiedCheckbox'),
prevRevSpeedVal = revSLMenu.value,
numSegsSelected = Waze.selectionManager.selectionCountByType.segment,
pauseTime = (numSegsSelected > 10) ? (50+numSegsSelected) : 0;
cmlog([5,3],speedVal);
if (revSL.disabled === false) {
document.getElementById('cmWaitCover').style.display = 'block';
speedVal = SL.checkUnits(speedVal);
requestAnimationFrame(function(){
var revChkBoxMenu = document.getElementById('revMaxSpeedUnverifiedCheckbox_cm');
if (revChkBoxMenu !== null) revChkBoxMenu.checked = true;
revSLMenu.value = speedVal;
});
setTimeout(function(){
if (revChkBox !== null && speedVal === prevRevSpeedVal) {
revChkBox.checked = true;
revChkBox.dispatchEvent(changeEvent);
} else if (revSL !== null) {
revSL.value = speedVal;
revSL.dispatchEvent(changeEvent);
//$(revSL).val(speedVal).change();
if (revChkBox !== null) setTimeout(function(){revChkBox.checked = true;},20);
}
if (!document.getElementById('cmPinMenu').value) setTimeout(closeContextMenu, 150);
else setTimeout(SL.highlightSpeedSigns,50);
document.getElementById('cmWaitCover').style.display = 'none';
},pauseTime);
}
};
SL.addSpeedSignBoth = function(speedVal) {
var fwdSLMenu = document.querySelector('input[name="fwdMaxSpeed_cm'),
revSLMenu = document.querySelector('input[name="revMaxSpeed_cm'),
fwdSL = document.querySelector('input[name="fwdMaxSpeed"]'),
revSL = document.querySelector('input[name="revMaxSpeed"]'),
fwdChkBox = document.getElementById('fwdMaxSpeedUnverifiedCheckbox'),
revChkBox = document.getElementById('revMaxSpeedUnverifiedCheckbox'),
prevFwdSpeedVal, prevRevSpeedVal,
numSegsSelected = Waze.selectionManager.selectionCountByType.segment,
pauseTime = (numSegsSelected > 10) ? 60 : 0;
cmlog([5,3],speedVal);
if ((revSLMenu && revSLMenu.parentNode.style.display === 'none') || revSLMenu === null) {
SL.addSpeedSignAB(speedVal);
} else if ((fwdSLMenu && fwdSLMenu.parentNode.style.display === 'none') || fwdSLMenu === null) {
SL.addSpeedSignBA(speedVal);
} else if (fwdSL.disabled === false && revSL.disabled === false) {
document.getElementById('cmWaitCover').style.display = 'block';
speedVal = SL.checkUnits(speedVal);
prevFwdSpeedVal = fwdSLMenu.value;
prevRevSpeedVal = revSLMenu.value;
requestAnimationFrame(function(){
var fwdChkBoxMenu = document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm'),
revChkBoxMenu = document.getElementById('revMaxSpeedUnverifiedCheckbox_cm');
if (fwdChkBoxMenu !== null) fwdChkBoxMenu.checked = true;
if (revChkBoxMenu !== null) revChkBoxMenu.checked = true;
fwdSLMenu.value = speedVal; //$('#cmSpeedLimit input[type="number"]').val(speedVal);
revSLMenu.value = speedVal;
});
setTimeout(function(){
if (fwdChkBox !== null && speedVal === prevFwdSpeedVal) {
fwdChkBox.checked = true;
fwdChkBox.dispatchEvent(changeEvent);
//$('#fwdMaxSpeedUnverifiedCheckbox').prop('checked', true).change();
} else if (fwdSL !== null) {
fwdSL.value = speedVal;
fwdSL.dispatchEvent(changeEvent);
//$('input[name="fwdMaxSpeed"]').val(speedVal).change();
}
if (revChkBox !== null && speedVal === prevRevSpeedVal) {
revChkBox.checked = true;
revChkBox.dispatchEvent(changeEvent);
//$('#revMaxSpeedUnverifiedCheckbox').prop('checked', true).change();
} else if (revSL !== null) {
//revSL.value = speedVal;
//revSL.dispatchEvent(changeEvent);
$('input[name="revMaxSpeed"]').val(speedVal).change();
if (fwdChkBox !== null) setTimeout(function(){fwdChkBox.checked = true;},20);
if (revChkBox !== null) setTimeout(function(){revChkBox.checked = true;},40);
}
if (fwdSL && parseInt(fwdSL.value) !== parseInt(speedVal)) fwdSL.value = speedVal;
if (revSL && parseInt(revSL.value) !== parseInt(speedVal)) revSL.value = speedVal;
if (!document.getElementById('cmPinMenu').value) setTimeout(closeContextMenu, 150);
else setTimeout(SL.highlightSpeedSigns,50);
/*setTimeout(function(){
try { //do it again just in case... sometimes necessary...
$('input[name="revMaxSpeed"]').val(speedVal).change();
} catch(err) {}
}, 150);*/
document.getElementById('cmWaitCover').style.display = 'none';
}, pauseTime);
}
};
SL.addListenersToSigns = function (forceBuildNewMenu) {
// Add clear SL button:
/*if (document.getElementById('btnCMClearSLs') === null) {
document.getElementById('signsholder_cm').innerHTML = '<div id="btnCMClearSLs" class="fa fa-ban"><div id="spd_0">0</div></div>' +
document.getElementById('signsholder_cm').innerHTML;
}*/
var cmSpeedSigns = document.getElementById('signsholder_cm').children;
for (var ss = cmSpeedSigns.length; ss--;) {
//--------------------------------------------------------------
cmSpeedSigns[ss].addEventListener('click', function (e) {
e.preventDefault();
var speedVal;
if (!this.classList.length || !this.classList.contains('cm-sl-verified')) {
speedVal = this.firstElementChild.innerHTML;
} else {
speedVal = 0;
}
if (e.shiftKey) { //AB - fwd
requestAnimationFrame(function(){
SL.addSpeedSignAB(speedVal);
});
} else if (e.ctrlKey || e.altKey || e.metaKey ) { //BA - rev
requestAnimationFrame(function(){
SL.addSpeedSignBA(speedVal);
});
} else {
requestAnimationFrame(function(){
SL.addSpeedSignBoth(speedVal);
});
}
}, false);
//--------------------------------------------------------------
cmSpeedSigns[ss].addEventListener('mousedown', function (ev) {
//console.info(this);
this.draggable = true;
if (document.getElementById('cmPinMenu').value) {
document.getElementById('cmContextMenu').removeEventListener('dragstart', allowMenuDrag, false);
document.getElementById('cmContextMenu').draggable = false;
window.addEventListener('mouseup', resetDrag, false);
}
}, false);
cmSpeedSigns[ss].addEventListener('dragstart', function (ev) {
//console.info(this);
this.style.opacity = 0.3;
this.children[0].opacity = 0.7;
ev.dataTransfer.setData('text', this.children[0].innerHTML);
ev.dataTransfer.setDragImage(this, ev.offsetX, ev.offsetY);
}, false);
cmSpeedSigns[ss].addEventListener('dragend', function (ev) {
this.style.opacity = '';
this.children[0].opacity = '';
this.draggable = false;
resetDrag();
window.removeEventListener('mouseup', resetDrag, false);
}, false);
}
//-----------------------------------------------
var slCurrentElementStatus =
[!!document.getElementById('fwdMaxSpeedUnverifiedCheckbox'),
!!document.getElementById('revMaxSpeedUnverifiedCheckbox'),
!!document.getElementsByName('fwdMaxSpeed').length,
!!document.getElementsByName('revMaxSpeed').length],
slMenuElementFlags =
[!!document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm')+1,
!!document.getElementById('revMaxSpeedUnverifiedCheckbox_cm')+1,
document.getElementsByName('fwdMaxSpeed_cm').length+1,
document.getElementsByName('revMaxSpeed_cm').length+1];
for (var cc = 4, slCurrentElementTotal=0; cc--;) {
slCurrentElementTotal += slCurrentElementStatus[cc];
}
if (forceBuildNewMenu === null || SL.speedhelperIsPresent === null) {
/*SL.signsContainerHTML = null;*/
} else {
if (forceBuildNewMenu === true && SL.speedhelperIsPresent === true) SL.reduceSpeedhelperOverhead();
if (forceBuildNewMenu === true || slCurrentElementTotal >= SL.slSavedMaxElementTotal) {
SL.cmMenuContentHTML = document.getElementById('cmMenuContent').innerHTML;
SL.slSavedMaxElementTotal = slCurrentElementTotal;
SL.slSavedMenuElementFlags = slMenuElementFlags;
cmlog([4,4],'*** SL.cmMenuContentHTML replaced ***');
}
}
SL.highlightSpeedSigns(); // this is necessarily at the end to play catchup bc of the slower initialization times of Speedhelper elements
};
//--------------------------------------------------------------------------
SL.populateSpeedMenu = function (contextMenuSettings, nodeLabel) {
cmlog([1,1], 'SL.populateSpeedMenu(contextMenuSettings, ' + nodeLabel + ')');
document.getElementById('cmMenuNoContent').style.display = 'none';
document.getElementById('cmMenuContent').style.display = 'block';
if (SL.menuResetEvent === true) SL.checkCountry();
var slCurrentElementStatus = [!!document.getElementById('fwdMaxSpeedUnverifiedCheckbox'),
!!document.getElementById('revMaxSpeedUnverifiedCheckbox'),
!!document.getElementsByName('fwdMaxSpeed').length,
!!document.getElementsByName('revMaxSpeed').length],
signholderEl, forceBuildNewMenu = SL.forceBuildNewMenu,
slMenuElementFlags = [!!document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm')+1,
!!document.getElementById('revMaxSpeedUnverifiedCheckbox_cm')+1,
document.getElementsByName('fwdMaxSpeed_cm').length+1,
document.getElementsByName('revMaxSpeed_cm').length+1];
if (forceBuildNewMenu === true) {
SL.forceBuildNewMenu = false;
SL.menuResetEvent = true;
SL.slSavedMenuElementFlags = false;
SL.slSavedMaxElementTotal = 0;
SL.cmMenuContentHTML = null;
SL.signsContainerHTML = null;
}
if (SL.slSavedMenuElementFlags === false) SL.slSavedMenuElementFlags = slMenuElementFlags;
for (var cc = 4, slNumSavedElementsMatched = 0, slNumElementsMatched = 0, slCurrentElementTotal=0; cc--;) {
slNumElementsMatched += (((slMenuElementFlags[cc]*slCurrentElementStatus[cc]-1)>0)===slCurrentElementStatus[cc]);
slNumSavedElementsMatched += (((SL.slSavedMenuElementFlags[cc]*slCurrentElementStatus[cc]-1)>0)===slCurrentElementStatus[cc]);
slCurrentElementTotal += slCurrentElementStatus[cc];
}
cmlog([4,3], 'SL.slSavedMaxElementTotal', SL.slSavedMaxElementTotal, '| slCurrentElementTotal', slCurrentElementTotal);
cmlog([4,3], 'slNumSavedElementsMatched', slNumSavedElementsMatched, '| slNumElementsMatched', slNumElementsMatched);
cmlog([4,3], 'SL.slSavedMenuElementFlags', SL.slSavedMenuElementFlags, '| slMenuElementFlags', slMenuElementFlags);
if ( forceBuildNewMenu === true || SL.cmMenuContentHTML === null || slNumElementsMatched !== 4 ||
(SL.menuResetEvent === true && slNumElementsMatched !== 4) ||
(slCurrentElementTotal === 4 && SL.slSavedMaxElementTotal !== 4) ) {
resetContextMenu(contextMenuSettings);
document.getElementById('cmMenuHeaderTitle').innerHTML = 'Edit Speed Limits <i class="fa fa-pencil fa-pull-right" style="font-size: 12px; cursor: pointer;"></i>';
if (SL.cmMenuContentHTML && slNumSavedElementsMatched === 4) {
cmlog([4,1],'Replace - Copy Saved and Rebuild');
document.getElementById('cmMenuContent').innerHTML = SL.cmMenuContentHTML;
SL.menuResetEvent = false;
} else { //TODO: I think slNumElementsMatched !== 4 is redundant with slNumSavedElementsMatched
/*(document.getElementsByName('fwdMaxSpeed').length && !document.getElementsByName('fwdMaxSpeed_cm').length) ||
(document.getElementsByName('revMaxSpeed').length && !document.getElementsByName('revMaxSpeed_cm').length)) {*/
SL.menuResetEvent = true;
try {
cmlog([4,1],'Replace - Overwrite with Source and Rebuild');
document.getElementById('cmMenuContent').innerHTML = document.querySelector('#segment-edit-general div.speed-limit').outerHTML;
speedLimit = document.getElementById('cmMenuContent').children[0];
speedLimit.innerHTML = '<div id="signsContainer" style="min-height: ' + ((SL.signsContainerHeight) ? (SL.signsContainerHeight + 'px; ') : 'auto; ') + 'margin-bottom: 10px; opacity: 0.9;"></div><div class="form-inline">' + speedLimit.innerHTML + '</div>';
speedLimit.id = 'cmSpeedLimit';
speedLimit.className = 'cm-speed-limit cm-menu-section';
signholderEl = document.querySelector('#cmSpeedLimit #signsholder')
if (SL.speedhelperIsPresent !== null && SL.signsContainerHTML !== null) {
document.getElementById('signsContainer').innerHTML = SL.signsContainerHTML;
} else if (signholderEl !== null) {
signholderEl.id = 'signsholder_cm';
document.getElementById('signsContainer').appendChild(document.getElementById('signsholder_cm')); // Move the signs to its own container
SL.reduceSpeedhelperOverhead();
SL.createSpeedSigns();
} else if (document.getElementById('cmSignsWait') === null) {
document.getElementById('cmSpeedLimit').innerHTML = '<div id="cmSignsWait"><p><i class="fa fa-spinner fa-pulse fa-lg"></i></p><p>Looking for WME Speedhelper...<br>Please wait a moment.</p></div>' +
document.getElementById('cmSpeedLimit').innerHTML;
}
} catch (err) {
cmlog([4,2],'Replace - Caught. No SpeedHelper or SpeedHelper is not ready.', err);
}
}
//--------------------------------------------------------------------------
try {
var wazeVerifyChkBoxLabel = document.querySelectorAll('#segment-edit-general div.speed-limit input[type="checkbox"]+label'),
wazeChkbox, wazeChkboxSelector;
// Add event listeners for verified SL checkbox in menu
for (var cb = 0; cb < wazeVerifyChkBoxLabel.length; cb++) {
wazeChkbox = wazeVerifyChkBoxLabel[cb].parentNode.children[0];
cmChkboxSelector = '#cmSpeedLimit ' + '#' + wazeChkbox.id;
if (SL.menuResetEvent) document.querySelector(cmChkboxSelector).id = wazeChkbox.id + '_cm';
document.querySelector(cmChkboxSelector + '_cm').addEventListener('click', function(e) {
e.stopPropagation();
this.parentNode.children[0].checked = !document.getElementById(this.parentNode.children[0].id.slice(0, -3)).checked;
}, false);
}
} catch (err) {cmlog([4,2], 'wazeVerifyChkBoxLabel', err);}
//--------------------------------------------------------------------------
try {
var wazeSpeedInput = document.querySelectorAll('#segment-edit-general div.speed-limit input[type="number"]'),
wazeSpeedInputLength = wazeSpeedInput.length,
cmSpeedInput, cmSpeedInputSelector_orig, cmSpeedInputSelector, nm;
for (nm = 0; nm < wazeSpeedInputLength; nm++) {
cmSpeedInputSelector_orig = '#cmSpeedLimit input[name="' + wazeSpeedInput[nm].name + '"]';
cmSpeedInputSelector = '#cmSpeedLimit input[name="' + wazeSpeedInput[nm].name + '_cm' + '"]';
if (SL.menuResetEvent) {
document.querySelector(cmSpeedInputSelector_orig).setAttribute('name', wazeSpeedInput[nm].name + '_cm');
}
cmSpeedInput = document.querySelector(cmSpeedInputSelector);
cmSpeedInput.addEventListener('click', function (e) {
e.stopPropagation();
this.select();
document.getElementById('cmContextMenu').removeEventListener('mouseenter', addHotkeyListener, false);
window.removeEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Editing speed value, so removing global hotkey listener');
}, false);
cmSpeedInput.addEventListener('blur', function (e) {
document.getElementById('cmContextMenu').addEventListener('mouseenter', addHotkeyListener, false);
window.addEventListener('keydown', menuShortcutKeys, true);
cmlog([2,2],'Removed focus from speed input field, so adding global hotkey listener again');
$('input[name="' + this.name.slice(0, -3) + '"]').val(this.value).change();
}, false);
cmSpeedInput.addEventListener('change', function (e) {
//e.stopPropagation();
$('input[name="' + this.name.slice(0, -3) + '"]').val(this.value).change();
}, false);
}
} catch (err) {cmlog([4,2], 'cmSpeedInput', err);}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
try { // Try adding some event listeners for closing the menu if not pinned:
if (!document.getElementById('cmPinMenu').value) {
document.getElementById('cmContextMenu').addEventListener(
'mouseleave',
function () {
cmlog([2,2], 'Adding event listners to allow menu to close');
addSpecialMenuListeners();
//$('input[name="fwdMaxSpeed_cm"]').val($('input[name="fwdMaxSpeed"]').val());
//$('input[name="revMaxSpeed_cm"]').val($('input[name="revMaxSpeed"]').val());
}, false);
document.getElementById('cmContextMenu').addEventListener(
'mouseenter',
function () { //prevent menu from closing
cmlog([2,2],'Preventing menu from closing by removing event listeners');
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
}, false);
}
} catch (err) { cmlog([4,2], 'addSpecialMenuListeners', err); }
//--------------------------------------------------------------------------
document.querySelector('#cmMenuHeaderTitle>.fa-pencil').onclick = SL.editSpeedSigns;
//--------------------------------------------------------------------------
// Add event listener for clearing SLs of each direction
var fwdSpeedEl = document.querySelector('input[name="fwdMaxSpeed_cm"]');
if (fwdSpeedEl) {
if (fwdSpeedEl.parentNode.querySelector('.fa-ban') === null) {
var clearSignFwd = document.createElement('span');
clearSignFwd.className = 'fa fa-ban';
fwdSpeedEl.parentNode.insertBefore(clearSignFwd, fwdSpeedEl.parentNode.children[0]);
clearSignFwd.addEventListener('click', function() {
requestAnimationFrame(function(){
SL.addSpeedSignAB(0);
});
}, false);
}
}
var revSpeedEl = document.querySelector('input[name="revMaxSpeed_cm"]');
if (revSpeedEl) {
if (revSpeedEl.parentNode.querySelector('.fa-ban') === null) {
var clearSignRev = document.createElement('span');
clearSignRev.className = 'fa fa-ban';
revSpeedEl.parentNode.insertBefore(clearSignRev, revSpeedEl.parentNode.children[0]);
clearSignRev.addEventListener('click', function() {
requestAnimationFrame(function(){
SL.addSpeedSignBA(0);
});
}, false);
}
}
// Add event listener for the checkbox
if (document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm') !== null) {
document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm').parentNode.addEventListener('click', function(e) {
this.children[0].checked = !this.children[0].checked;
}, false);
}
if (document.getElementById('revMaxSpeedUnverifiedCheckbox_cm') !== null) {
document.getElementById('revMaxSpeedUnverifiedCheckbox_cm').parentNode.addEventListener('click', function(e) {
this.children[0].checked = !this.children[0].checked;
}, false);
}
// Add event listeners for drag-drop events
var fwdSpeedEl = document.querySelector('input[name="fwdMaxSpeed_cm"]');
if (fwdSpeedEl) {
// Allow drop event
fwdSpeedEl.addEventListener('dragover', function(ev) {
if (ev.preventDefault()) ev.preventDefault();
this.style.border = '1px solid cyan';
return false;
}, false);
fwdSpeedEl.addEventListener('dragleave', function(ev) {
this.style.border = '';
}, false);
// Drop event
fwdSpeedEl.addEventListener('drop', function(ev) {
if (ev.preventDefault()) ev.preventDefault();
var speedVal = ev.dataTransfer.getData('text');
requestAnimationFrame(function(){
SL.addSpeedSignAB(speedVal);
});
this.style.border = '';
}, false);
}
var revSpeedEl = document.querySelector('input[name="revMaxSpeed_cm"]');
if (revSpeedEl) {
// Allow drop event
revSpeedEl.addEventListener('dragover', function(ev) {
if (ev.preventDefault()) ev.preventDefault();
this.style.border = '1px solid cyan';
return false;
}, false);
revSpeedEl.addEventListener('dragleave', function(ev) {
this.style.border = '';
}, false);
// Drop event
revSpeedEl.addEventListener('drop', function(ev) {
if (ev.preventDefault()) ev.preventDefault();
var speedVal = ev.dataTransfer.getData('text');
requestAnimationFrame(function(){
SL.addSpeedSignBA(speedVal);
});
this.style.border = '';
}, false);
}
//--------------------------------------------------------------------------
var waitCount = 0,
maxWait = 19, //~5 seconds
signsContainerEl = document.getElementById('signsContainer');
var waitForSpeedhelper = function () {
var originalSpeedhelperEl = document.querySelector('#segment-edit-general div.speed-limit #signsholder');
if (signsContainerEl.children.length === 0 || SL.speedhelperIsPresent === null) {
if (originalSpeedhelperEl !== null) {
SL.menuResetEvent = false;
SL.speedhelperIsPresent = true;
signsContainerEl.innerHTML = originalSpeedhelperEl.outerHTML;
document.querySelector('#signsContainer>#signsholder').id = 'signsholder_cm';
setTimeout(function(){SL.signsContainerHeight = $('#signsholder_cm').height();},200);
SL.reduceSpeedhelperOverhead();
SL.createSpeedSigns();
SL.addListenersToSigns(forceBuildNewMenu);
} else if (waitCount++ < maxWait) {
setTimeout(waitForSpeedhelper, 30*waitCount);
if (waitCount===10 && SL.speedhelperIsPresent === null) { //~1.5seconds ?
SL.createSpeedSigns();
SL.addListenersToSigns(null);
}
} else {
SL.menuResetEvent = false;
SL.signsContainerHeight = false;
SL.speedhelperIsPresent = false;
SL.createSpeedSigns();
SL.addListenersToSigns(forceBuildNewMenu);
}
}
return;
};
//------------------------------------------------------
setTimeout(function () {
if (signsContainerEl && signsContainerEl.children.length) {
SL.menuResetEvent = false;
setTimeout(function(){SL.signsContainerHeight = $('#signsholder_cm').height();},200);
SL.addListenersToSigns(forceBuildNewMenu);
} else if (SL.speedhelperIsPresent !== false) {
setTimeout(waitForSpeedhelper, 30);
} else { // SL.speedhelperIsPresent === false
SL.menuResetEvent = false;
SL.createSpeedSigns();
SL.addListenersToSigns(forceBuildNewMenu);
}
}, 30); //timeout may be needed for countries with many speedlimit signs loaded by Speedhelper
//------------------------------------------------------
}
var $fwdSL = $('input[name="fwdMaxSpeed"]'), hasFwdSL = ($fwdSL.length && !$fwdSL.prop('disabled')),
$revSL = $('input[name="revMaxSpeed"]'), hasRevSL = ($revSL.length && !$revSL.prop('disabled')),
hasOnlyOneSL = !(hasFwdSL && hasRevSL),
fwdSLMenu = document.querySelector('input[name="fwdMaxSpeed_cm"]'),
revSLMenu = document.querySelector('input[name="revMaxSpeed_cm"]'),
fwdChkBox, revChkBox, fwdMenuChkBox, revMenuChkBox;
cmlog([5,3], 'hasFwdSL', hasFwdSL, 'hasRevSL', hasRevSL, 'hasOnlyOneSL', hasOnlyOneSL, 'nodeLabel', nodeLabel);
if (hasFwdSL || hasRevSL) {
fwdMenuChkBox = document.getElementById('fwdMaxSpeedUnverifiedCheckbox_cm');
fwdChkBox = document.getElementById('fwdMaxSpeedUnverifiedCheckbox');
revMenuChkBox = document.getElementById('revMaxSpeedUnverifiedCheckbox_cm');
revChkBox = document.getElementById('revMaxSpeedUnverifiedCheckbox');
// Update values of the context menu
// Hide input fields that aren't relevant for selected segment(s)
if (fwdSLMenu !== null) {
fwdSLMenu.disabled = false;
if (hasOnlyOneSL || nodeLabel !== 'B') {
if (hasFwdSL) {
fwdSLMenu.value = $fwdSL.val();
fwdSLMenu.parentNode.style.display = 'inline-block';
if (fwdMenuChkBox !== null) {
fwdMenuChkBox.disabled = false;
if (fwdChkBox !== null) {
fwdMenuChkBox.checked = fwdChkBox.checked;
fwdMenuChkBox.parentNode.style.visibility = 'visible';
fwdMenuChkBox.parentNode.style.display = 'inline-block';
} else {
fwdMenuChkBox.parentNode.style.visibility = 'hidden';
fwdMenuChkBox.parentNode.style.display = 'inline-block';
}
}
} else {
fwdSLMenu.parentNode.style.display = 'none';
if (fwdMenuChkBox !== null) fwdMenuChkBox.parentNode.style.display = 'none';
}
} else {
fwdSLMenu.parentNode.style.display = 'none';
if (fwdMenuChkBox !== null) fwdMenuChkBox.parentNode.style.display = 'none';
}
}
if (revSLMenu !== null) {
revSLMenu.disabled = false;
if (hasOnlyOneSL || nodeLabel !== 'A') {
if (hasRevSL) {
revSLMenu.value = $revSL.val();
revSLMenu.parentNode.style.display = 'inline-block';
if (revMenuChkBox !== null) {
revMenuChkBox.disabled = false;
if (revChkBox !== null) {
revMenuChkBox.checked = revChkBox.checked;
revMenuChkBox.parentNode.style.visibility = 'visible';
revMenuChkBox.parentNode.style.display = 'inline-block';
} else {
revMenuChkBox.parentNode.style.visibility = 'hidden';
revMenuChkBox.parentNode.style.display = 'inline-block';
}
}
} else {
revSLMenu.parentNode.style.display = 'none';
if (revMenuChkBox !== null) revMenuChkBox.parentNode.style.display = 'none';
}
} else {
revSLMenu.parentNode.style.display = 'none';
if (revMenuChkBox !== null) revMenuChkBox.parentNode.style.display = 'none';
}
}
SL.highlightSpeedSigns();
} else {
cmlog([4,2],'No SL. Hiding...');
document.getElementById('cmMenuNoContent').style.display = 'block';
document.getElementById('cmMenuContent').style.display = 'none';
}
//--------------------------------------------------------------------------
};
//==============================================================================================
var selectedItemsIsSegment = function () {
var sel = Waze.selectionManager.selectedItems, //returns empty array if nothing
selLength = sel.length,
s, segments = [];
cmlog([1,1], 'selectedItemsIsSegment()');
for (s = 0; s < selLength; s++) {
if (sel[s].model.type === 'segment') segments.push(sel[s]);
}
return (segments.length) ? {nodeLabel: false, segments: segments} : false;
};
//----------------------------------------------------------------------------------------------
var selectionIsSegment = function (e) {
cmlog([1,1], 'selectionIsSegment(e)')
var sel, selLength, s, segments = [],
numSelected, eventFeatures, evTarget, nodeLabel = false;
// First check for segments under cursor (hover/mouseover)
if (e && e.target) {
evTarget = $(e.target).get(0); //normalization by jQuery is necessary for FF compatibility
} else {
evTarget = false;
}
if (evTarget && evTarget._featureId &&
(evTarget._geometryClass === "OpenLayers.Geometry.LineString" ||
evTarget._geometryClass === "OpenLayers.Geometry.Point")) {
e.preventDefault();
if (evTarget._geometryClass === "OpenLayers.Geometry.Point" && evTarget._style) {
cmlog([1,3], evTarget._featureId, evTarget._geometryClass, evTarget._style.label);
if (evTarget._style.label === 'A') {
nodeLabel = 'A';
} else if (evTarget._style.label === 'B') {
nodeLabel = 'B';
}
}
sel = Waze.selectionManager.selectedItems; //returns empty array if nothing
selLength = sel.length;
eventFeatures = Waze.map.segmentLayer.getFeatureById(evTarget._featureId); //segment layer -- returns null if nothing
//cmlog([1,0], 'eventFeatures =')
//console.debug(eventFeatures);
if (eventFeatures && eventFeatures.model.type === 'segment') {
segments[0] = eventFeatures; //return result from W.map.segmentLayer.getFeatureById(._featureId) is the same as individual objects within the array returned by W.selectionManager.selectedItems
try {
//cmlog([1,0],'SegID:',eventFeatures.model.attributes.id);
Waze.selectionManager.select([eventFeatures.model]); // [eventFeatures.model] is the same as the return result for one seg from W.model.segments.getByIds([id])
} catch(err) { cmlog([1,0], '<tantrum>'); console.error(err); }
}
//Now check for any selected segments... any duplicates of the hovered
//segment will be dealt with in the next steps using object literals
try {
for (s = 0; s < selLength; s++) {
if (sel[s].model.type === 'segment') segments.push(sel[s]);
}
} catch(err) {
if (e.type === 'selectionchanged') {
sel = e.selected;
selLength = sel.length;
for (s = 0; s < selLength; s++) {
if (sel[s] && sel[s].model.type === 'segment') segments.push(sel[s]);
}
}
}
//console.info(segments);
document.getElementById('cmMenuNoContent').style.display = 'none';
document.getElementById('cmMenuContent').style.display = 'block';
return (segments.length) ? {nodeLabel: nodeLabel, segments: segments} : false; //no segments near cursor
} else if (e.type === 'selectionchanged') {
sel = e.selected;
selLength = sel.length;
for (s = 0; s < selLength; s++) {
if (sel[s] && sel[s].model.type === 'segment') segments.push(sel[s]);
}
return (segments.length) ? {nodeLabel: false, segments: segments} : false; //no segments near cursor
} else {
return false;
}
};
//----------------------------------------------------------------------------------------------
var setupSegmentContextMenu = function (e) {
cmlog([1,0],'------------------------------------------------------------')
cmlog([1,1], 'setupSegmentContextMenu()');
if (document.getElementById('cmContextMenu') && document.getElementById('cmContextMenu').style.display !== 'none') {
var selectedStuff = selectionIsSegment(e);
if (selectedStuff) {
if (document.getElementById('cmRSel').value && document.getElementById('cmRSelAutoAdd'))
document.getElementById('cmRSelAutoAdd').style.display = 'block';
switch (contextMenuSettings.clipboard) {
case 2:
SL.populateSpeedMenu(contextMenuSettings, selectedStuff.nodeLabel);
break;
case 1:
case 0:
var segInfo = getSegmentProperties(selectedStuff);
populateCopyMenu(segInfo, contextMenuSettings);
break;
}
} else if (document.getElementById('cmPinMenu').value) {
if (document.getElementById('cmRSelAutoAdd'))
document.getElementById('cmRSelAutoAdd').style.display = 'none';
document.getElementById('cmMenuNoContent').style.display = 'block';
document.getElementById('cmMenuContent').style.display = 'none';
return false;
} else {
cmlog([1,1],'No segment detected.')
return false;
}
} else {
return false;
}
};
//=======================================================================================
//var pressedKeys = [];
var menuShortcutKeys = function (e) {
cmlog([1,1], 'menuShortcutKeys()');
switch (e.which) {
case 49: //81: //q
e.preventDefault();
e.stopPropagation();
document.getElementById('cmClipboard').click();
break;
case 50: //87: //w
e.preventDefault();
e.stopPropagation();
document.getElementById('cmRSel').click();
break;
case 51: //69: //e
e.preventDefault();
e.stopPropagation();
document.getElementById('cmSpeed').click();
break;
default:
return false;
}
};
//--------------------------------------------------------------------------------
var cursorOffsetX, cursorOffsetY;
var moveMenu = function (evt) {
//cmlog([1],'moveMenu()');
try {
evt.preventDefault();
evt.stopPropagation();
//evt.dataTransfer.effectAllowed = 'move';
requestAnimationFrame( function() {
document.getElementById('cmContextMenu').classList.add('cm-drag');
document.getElementById('cmContextMenu').style.top = evt.clientY - cursorOffsetY + 'px';
document.getElementById('cmContextMenu').style.left = evt.clientX - cursorOffsetX + 'px';
});
} catch (err) { console.error(err); }
};
var placeMenu = function (endevt) {
cmlog([1,1], 'placeMenu()');
endevt.preventDefault();
//endevt.dataTransfer.dropEffect = 'move';
try {
//document.getElementById('cmContextMenu').style.display = 'block';
setTimeout(function(){document.getElementById('cmContextMenu').classList.remove('cm-drag')},50);
if (!isFirefox) {
document.getElementById('cmContextMenu').style.display = 'block';
document.getElementById('cmContextMenu').removeEventListener('drag', moveMenu, false);
} else {
window.removeEventListener('mousemove', moveMenu, true);
window.removeEventListener('mouseup', placeMenu, true);
}
} catch (err) { console.error(err); }
};
var allowMenuDrag = function (startevt) {
cmlog([1,1], 'allowMenuDrag()');
//console.info(startevt);
try {
if (document.getElementById('cmContextMenu').draggable) {
document.getElementById('cmContextMenu').classList.add('cm-drag');
if (!isFirefox) {
setTimeout(function(){document.getElementById('cmContextMenu').style.display = 'none';},20);
cursorOffsetX = startevt.offsetX;
cursorOffsetY = startevt.offsetY;
document.getElementById('cmContextMenu').addEventListener('drag', moveMenu, false);
} else {
startevt.preventDefault();
startevt.stopPropagation();
cursorOffsetX = startevt.layerX;
cursorOffsetY = startevt.layerY;
window.addEventListener('mousemove', moveMenu, true);
window.addEventListener('mouseup', placeMenu, true);
}
}
} catch (err) { console.error(err); }
};
// Setup dragging for when menu is pinned to page
var dragMenuSetup = function(pinState) {
if (pinState === undefined) pinState = document.getElementById('cmPinMenu').value;
var contextMenu = document.getElementById('cmContextMenu'),
mapDiv = document.getElementById('map');
if (pinState && contextMenu.draggable === false) {
contextMenu.draggable = true;
contextMenu.addEventListener('dragstart', allowMenuDrag, false);
if (!isFirefox) {
mapDiv.addEventListener('drop', placeMenu, false);
mapDiv.ondragover = function (e) {
e.preventDefault();
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.dropEffect = 'move';
};
}
} else if (!pinState && contextMenu.draggable === true) {
contextMenu.draggable = false;
contextMenu.removeEventListener('dragstart', allowMenuDrag);
if (!isFirefox) {
mapDiv.removeEventListener('drop', placeMenu);
}
}
};
//for preventing conflicts with SL sign drags
var resetDrag = function() {
window.removeEventListener('mouseup', resetDrag, false);
dragMenuSetup();
};
//=======================================================================================
var showPopupPanel = function(updateVersion, updateText, forumURL) {
var popPanelWidth = 600,
popPanelCSS = document.createElement('style'),
popPanelHTML = document.createElement('div');
popPanelCSS.type = 'text/css';
popPanelCSS.id = 'cssCMupdate';
popPanelCSS.innerHTML =
'.cm-panel { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);' +
' width: ' + popPanelWidth + 'px; padding: 10px 25px; margin: 0; overflow-y: auto; overflow-x: auto; word-wrap: break-word;' +
' background-color: white; box-shadow: 0px 5px 20px #555555; border: 1px solid #858585; border-radius: 10px; }\n' +
'.cm-panel .fa-exclamation-circle { margin: -5px 16px 10px 8px; line-height: .9; font-size: 56px;}\n' +
'.cm-panel-inner { padding: 0px 5px; }\n' +
'.cm-panel-section {display: block; font-size: 14px; margin-bottom: 10px; text-align: left; padding: 0px; }\n' +
'.cm-panel h2 { margin-top: 15px; margin-left: 80px; font-size: 32px; font-weight: bold; text-align: left; color: #C0C0C0 }\n' +
'.cm-panel-hr { display: 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); margin-top: 8px; margin-bottom: 15px; }\n' +
'.cm-panel .cm-btn-container { position: relative; display: table; margin: 0px auto 8px; vertical-align: middle; padding: 0}\n' +
'.cm-panel .btn { margin: 0px 5px; padding: 0px 15px; display: inline-block; height: 32px; }\n';
document.body.appendChild(popPanelCSS);
popPanelHTML.id = 'divCMupdate';
popPanelHTML.style.backgroundColor = 'rgba(0,0,0,0.5)';
popPanelHTML.style.position = 'fixed';
popPanelHTML.style.top = 0;
popPanelHTML.style.right = 0;
popPanelHTML.style.bottom = 0;
popPanelHTML.style.left = 0;
popPanelHTML.style.zIndex = 5001;
popPanelHTML.innerHTML = '<div class="cm-panel">' +
'<div margin-bottom: 20px; margin-top: 20px;>' +
'<i class="fa fa-exclamation-circle fa-pull-left"></i>' +
'<h2>WMECM Update Notes</h2>' +
'<hr class="cm-panel-hr"></div>' +
'<div class="cm-panel-inner"><div class="cm-panel-section">' +
updateText +
'</div>' +
'<div style="margin-top: 10px; font-size: 10.1pt">' +
'For details and screenshots or to report a bug, please visit the forum post: <a href="' + forumURL + '" target="_blank"><i class="fa fa-external-link"></i></a>' +
'</div>' +
'<div style="margin-top: 10px; font-style: italic; font-size: 10px;"> ' +
'WME Context Menu update for min. version ' + updateVersion +
'</div></div>' +
'<hr class="cm-panel-hr">' +
'<div class="cm-btn-container">' +
'<button id="btnCMokay" class="btn btn-default">OK</button>' +
'</div></div>';
document.body.appendChild(popPanelHTML);
document.getElementById('btnCMokay').onclick = function() {
document.getElementById('divCMupdate').remove();
document.getElementById('cmUpdateNote').classList.remove('cm-unread');
document.getElementById('cssCMupdate').remove();
requestAnimationFrame(function(){CMenuVersion.updateVersionString(minVersion)});
};
};
//=======================================================================================
var switchPanelTo = function(panelName) {
switch (panelName) {
case 'clipboard':
document.getElementById('cmClipboard').value = true;
document.getElementById('cmClipboard').classList.remove('toggle-off');
document.getElementById('cmRSel').value = false;
document.getElementById('cmRSel').classList.add('toggle-off');
document.getElementById('cmSpeed').value = false;
document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
document.getElementById('cmContextMenu').style.width = '210px';
break;
case 'rsel':
document.getElementById('cmClipboard').value = false;
document.getElementById('cmClipboard').classList.add('toggle-off');
document.getElementById('cmRSel').value = true;
document.getElementById('cmRSel').classList.remove('toggle-off');
document.getElementById('cmSpeed').value = false;
document.getElementById('cmSpeed').parentNode.style.opacity = 0.4;
document.getElementById('cmContextMenu').style.width = '210px';
break;
case 'speed':
document.getElementById('cmClipboard').value = false;
document.getElementById('cmClipboard').classList.add('toggle-off');
document.getElementById('cmRSel').value = false;
document.getElementById('cmRSel').classList.add('toggle-off');
document.getElementById('cmSpeed').value = true;
document.getElementById('cmSpeed').parentNode.style.opacity = 0.84;
document.getElementById('cmContextMenu').style.width = '220px';
SL.signsContainerHeight = null;
break;
}
};
var showEmptyPanel = function(panelName) {
switch (panelName) {
case 'clipboard':
document.getElementById('cmMenuHeaderTitle').innerHTML = 'Copy To Clipboard';
document.getElementById('cmMenuNoContent').style.display = 'block';
document.getElementById('cmMenuContent').style.display = 'none';
break;
case 'rsel':
if (document.getElementById('cmRSelAutoAdd')) document.getElementById('cmRSelAutoAdd').style.display = 'none';
document.getElementById('cmMenuHeaderTitle').innerHTML = 'Send To Road Selector';
document.getElementById('cmMenuNoContent').style.display = 'block';
document.getElementById('cmMenuContent').style.display = 'none';
break;
case 'speed':
document.getElementById('cmMenuHeaderTitle').innerHTML = 'Edit Speed Limits';
document.getElementById('cmMenuNoContent').style.display = 'block';
document.getElementById('cmMenuContent').style.display = 'none';
break;
}
};
//=======================================================================================
var initContextMenu = function () {
cmlog([1,1], 'initContextMenu()');
var contextMenuActiveArea = document.createElement('div'),
contextMenu = document.createElement('div'),
contextMenuCSS = document.createElement('style'),
menuCSS;
try {//opacity: 0.5;
contextMenuCSS.type = 'text/css';
menuCSS = '#cmContextMenu { display: block; opacity: 1; }\n' +
'#cmContextMenu.cm-drag { cursor: move; opacity: 0.75 !important; transition: opacity .1s linear 0s; }\n' +
'.cm-top { border-top-right-radius: 3px; border-top-left-radius: 3px; }\n' +
'.cm-bottom { border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; }\n' +
'#cmFooter+#cmContainer .cm-menu-header>dl, #cmFooter+#cmContainer .cm-menu-header>dl>dt, #cmFooter+#cmContainer .cm-rsel>dl, #cmFooter+#cmContainer .cm-rsel>dl>dt, .cm-rsel+.cm-menu-header>dl, .cm-rsel+.cm-menu-header>dl>dt { border-radius: 0; }\n' +
'#cmFooter+#cmContainer #cmMenuContent > div:last-child { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; }\n' +
'.cm-footer-icns { font-size: 13px; margin: 0px 4px 0px 2px; cursor: pointer; display: inline-table; line-height: 1; }\n' +
'.cm-footer-icns:active, .cm-footer-icns:focus, .cm-footer-icns.toggle-off:active, .cm-footer-icns.toggle-off:focus { color: #64D8EA; }\n' +
'.cm-footer-icns.toggle-off, .cm-footer-text.toggle-off { color: #8CBBCC; }\n' +
'.cm-update-note { z-index: 3; cursor: pointer; color: #59899E; margin-top: -15px; position: relative; float: right; right: 5px; bottom: 2px; opacity: .8; line-height: 1; font-size: 14px; }\n' +
'.cm-update-note.cm-unread { color: crimson; }\n' +
'div.cm-menu-header { padding: 0px; border: 0; height: 20px; }\n' +
'.cm-menu-header dl { background-color: rgba(147, 196, 211, 0.92); padding: 0; border-top-right-radius: 4px; border-top-left-radius: 4px; }\n' +
'.cm-menu-header dt { padding: 4px 11px; text-transform: uppercase; line-height: 1.3; background-color: rgba(111, 167, 185, 0.7); color: #D8E9EF; font-size: 10px; border-top-right-radius: 3px; border-top-left-radius: 3px; height: 22px; margin-top: 1px; box-shadow: 0px -1px 0px #9ACCDC; }\n' +
'div.cm-menu-section { z-index: 2; border-bottom: 1px solid #416B7C; padding: 2px 0px 3px; background-color: rgba(147, 196, 211, 0.92); }\n' +
'.cm-menu-section dl { margin: 0; padding: 0; display: block; }\n' +
'.cm-menu-section dt { font-size: 9px; padding: 0px 6px 0px 20px; margin-top: 2px; text-transform: uppercase; line-height: 1.2; }\n' +
'.cm-menu-section dd { display: inherit; padding: 0px 14px 0px 20px; font-size: 11px; color: #234350; font-weight: 600; line-height: 1.3; word-break: break-all;}\n' +
'.cm-menu-section dd:hover, .cm-menu-section dd:active, .cm-menu-section dd:focus { cursor: default; background-color: #BEDCE5; color: #416B7C; }\n' +
'.cm-menu-section dd:active { color: #64D8EA; }\n';
menuCSS +=
'.cm-menu-section .cm-hide.fa-caret-down, .cm-menu-section .cm-hide.fa-caret-up { position: absolute; left: 8px; width: 90%; cursor: pointer; }\n' +
'.cm-menu-section .cm-hide.fa-caret-down { display: block; }\n' +
'.cm-menu-section .cm-hide.fa-caret-up { display: none; }\n' +
'.cm-menu-section.cm-hidden .cm-hide.fa-caret-down { display: none; }\n' +
'.cm-menu-section.cm-hidden .cm-hide.fa-caret-up { display: block; }\n' +
'.cm-hidden { height: 19px; }\n' +
'.cm-hidden dd { display: none; }\n' +
'.cm-hidden dt, .cm-hidden dl {float: left; margin-right: -12px; color: rgba(255, 255, 255, 0.7); }\n' +
'.cm-hidden dl:nth-of-type(2)>dt:before { content: "/ "; }\n' +
'dd.cm-paste { font-style: italic; text-align: right; max-width: 50%; float: right; padding: 0px 10px 0px 5px;}\n' +
'.cm-paste:before { content: ""; font-style: normal; font-weight: 400; color: black; font-size: 11px; margin-right: 2px; }\n';
menuCSS +=
'dd.cm-rsel-goselect { padding-right: 12px; padding-left: 12px; cursor: pointer; }\n' +
'.cm-menu-section .cm-rsel-goselect:hover { background-color: transparent; color: #d4e7ed; }\n' +
'.cm-rsel { display: none; border: 0; background-color: rgba(154, 204, 220, 0.9); border-top-right-radius: 3px; border-top-left-radius: 3px; margin-bottom: -1px; }\n' +
'.cm-rsel>dl { padding-top: 1px; border-top-right-radius: 4px; border-top-left-radius: 4px; }\n' +
'.cm-rsel>dl>dt { background-color: rgba(111, 167, 185, 0.7); height: 20px; margin-top: -2px; border-top-right-radius: 3px; border-top-left-radius: 3px; padding: 4px 10px; color: #d8e9ef; font-size: 10px; }\n' +
'.cm-rsel>dl>dt+dd { height: 24px; margin: 0px 0px 3px; padding: 5px 10px 5px 9px; background-color: rgba(228, 248, 255, 0.3); box-shadow: 0px 1px 0px rgba(0,0,0,0.1); }\n' +
'.cm-rsel-options, cm-rsel-options:focus:hover, cm-rsel-options+input:not(checked) { z-index: 2; background-color: rgba(89, 137, 158, 0.60); color: #D4E7ED; font-weight: bold !important; height: 14px !important; line-height: 1; padding: 3px 6px; font-size: 8px !important; border-radius: 15px; }\n' +
'.cm-rsel-options:hover { background-color: rgba(89, 137, 158, 0.7); color: white; }\n' +
'.cm-rsel-options.active:hover { background-color: #274B5A }\n' +
'.cm-rsel-options.active, .cm-rsel-options:active, .cm-rsel-options:active:focus { color: white; background-color: #3F6271; }\n' +
'.cm-rsel-options:focus { color: white; }\n' +
'.cm-rsel-options.and { background-color: #EEE; color: #59899E; border-right: 1px solid #AAA;}\n' +
'.cm-rsel-options.cm-badge-right { border-left: 1px solid #59899E; }\n';
menuCSS +=
'.cm-speed-limit.cm-menu-section { z-index: 3; width: 100%; font-size: 11px; text-align: center; display: inline-block; padding: 10px 8px; }\n' +
'.cm-speed-limit input[type="number"] { height: 28px; width: 50px; font-size: 12px; padding: 4px 5px; line-height: 1; margin: 0px 2px; }\n' +
'.cm-speed-limit input[type="checkbox"]+label { color: transparent; width: 10px; margin-left: 5px; vertical-align: middle; }\n' +
'.cm-speed-limit .controls-container { margin-left: 5px; }\n' +
'.cm-speed-limit div { border-radius: 3px; display: inline-block; }\n' +
'div#signsholder_cm>div#btnCMClearSLs { float: left; display: inline-block; cursor: pointer; background-image: none; color: #134C65; font-size: 28px; }\n' +
'div#signsholder_cm>div#btnCMClearSLs>div {display: none;}\n' +
'div#signsholder_cm>div#btnCMClearSLs:before { vertical-align: middle; }\n' +
'div#signsholder_cm>div:not(#btnCMClearSLs):before { position: absolute; background-color: white; color: black; border: 2px solid #00ECE3; font-weight: 400; border-radius: 50%; font-size: 9px; width: 16px; height: 16px; line-height: 12px; text-align: center; margin-left: -10px; margin-top: -3px; box-shadow: 0px 1px 1px gray; z-index: 1; }\n' +
'div#signsholder_cm>.cm-a:before { content: "A"; }\n' +
'div#signsholder_cm>.cm-b:before { content: "B"; }\n' +
'.cm-speed-limit>.form-inline .fa-ban { cursor: pointer; color: #1F576E; padding-right: 8px; font-size: 1.5em; font-weight: bold; vertical-align: middle; margin-bottom: 2px; }\n' +
'.cm-sl-edit>.fa-pencil:hover, .cm-speed-limit>.form-inline .fa-ban:hover { color: #00ECE3; }\n' +
'.cm-sl-verified { box-shadow: inset 0px 0px 0px 2px lime; }\n' +
'.cm-sl-unverified { box-shadow: inset 0px 0px 0px 2px gold; }\n' +
'.cm-sl-multisegs { box-shadow: inset 0px 0px 0px 3px #333 !important; }\n' +
'.cm-sl-verified.cm-both { box-shadow: 0px 0px 0px 1px lime, inset 0px 0px 0px 2px greenyellow; }\n' +
'.cm-sl-unverified.cm-one { box-shadow: 0px 0px 0px 1px lime, inset 0px 0px 0px 2px rgba(255, 235, 59, 1); }\n' +
'.cm-sl-unverified.cm-both { box-shadow: 0px 0px 0px 1px orange, inset 0px 0px 0px 2px rgba(255, 235, 59, 1); }\n' +
'#signsholder_cm>#signsError { float: initial; width: 100%; height: initial; padding: 5px 5px 5px 45px !important; text-align: left; }\n';
contextMenuCSS.innerHTML = menuCSS;
document.head.appendChild(contextMenuCSS);
//#btnCMAddSL {float: left; display: inline-block; cursor: pointer; color: #134C65; font-size: 24px; padding: 2px; width: 32px; line-height: 1;}
//#signsContainer.cm-sl-edit>#signsholder_cm>div:not(#btnCMclearSLs):after {content: "x"; position: absolute; background-color: #E53935; color: #FFF; font-weight: 600; border-radius: 50%; font-size: 11px; width: 14px; height: 14px; line-height: 12px; text-align: center; right: -3px; top: -4px; box-shadow: 0px 1px 1px gray;}
// reminder to self: no need to declare CSS here since this is put into DOM once and does not get destroyed
contextMenu.id = 'cmContextMenu';
contextMenu.style.position = 'fixed';
contextMenu.style.top = '0px';
contextMenu.style.left = '0px';
contextMenu.style.width = '210px';
contextMenu.style.margin = '0px';
contextMenu.style.padding = '0px';
contextMenu.style.borderRadius = '4px';
contextMenu.style.boxShadow = '0px 5px 12px rgba(0, 0, 0, 0.5)';
contextMenu.style.border = '1px solid rgb(89, 137, 150)';
contextMenu.style.borderBottom = '1px solid #2D505F';
contextMenu.style.color = 'white';
contextMenu.style.zIndex = '5000';
contextMenu.style.display = 'none';
contextMenu.style.opacity = 0;
contextMenu.innerHTML = '<div id="cmContainer" style="z-index: 2; color: white; padding:0; margin:0; position: relative; width: 100%; display: block;"></div>' +
'<div id="cmUpdateNote" class="fa fa-exclamation-circle cm-update-note"></div>' +
'<div id="cmFooter" class="cm-bottom" style="color: #DDEDF3; height: 24px; background-color: rgba(75, 125, 148, 0.85); ' +
'z-index: 3; padding: 1px 7px 1px; margin: 0; position: relative; width: 100%; display: block;"></div>';
document.getElementById('map').appendChild(contextMenu);
document.getElementById('cmFooter').innerHTML =
'<div style="position: relative; float: left; vertical-align: middle;">' +
'<i id="cmPinMenu" class="fa fa-thumb-tack cm-footer-icns toggle-off" style="margin: 0 0 0 -3px; padding: 3px 6px;" value=true title="Pin menu" data-toggle="tooltips"></i>' +
'<span id="cmPinClose" class="cm-footer-text toggle-off" style="cursor: pointer; font-weight: 600; border-left: 1px solid #D4E7ED; padding-left: 8px; text-transform: uppercase; font-size: 10px; letter-spacing: .7px;">Close</span>' +
'</div>' +
'<div id="cmFooterCaret" class="fa fa-angle-up cm-footer-icns pull-right" style="position: relative; top: 3px; margin: auto -1px auto 7px; font-weight: bold;"></div>' +
'<div style="position: relative; height: 21px; border-radius: 20px; border: 1px solid #6EA1B7; padding: 0px 1px 0px 5px;" class="btn-group pull-right">' +
'<div style="position: relative; display: inline-block; height: 100%; border-right: 1px solid #6EA1B7; padding-left: 2px; width: 22px;" class="">' +
'<i id="cmClipboard" value="false" style="font-size: 13px;" class="fa fa-clipboard cm-footer-icns toggle-off" title="Copy to Clipboard" data-toggle="tooltips"></i>' +
'</div>' +
'<div style="position: relative; display: inline-block; height: 100%; border-right: 1px solid #6EA1B7;">' +
'<i id="cmRSel" style="font-size: 14px;" value="false" class="fa fa-road cm-footer-icns toggle-off" title="Copy to WME Road Selector" data-toggle="tooltips"></i>' +
'</div>' +
'<div style="position: relative; display: inline-block; width: 20px; margin: 0; opacity: 0.84;">' +
'<span id="cmSpeed" style="height: 16px" value="false" title="Edit Speed Limits" class="fa fa-stack">' +
'<i class="fa fa-circle cm-footer-icns" style="font-size: 15px; width: 15px; color: #EEE; line-height: 14px; position: absolute; left: 0; text-align: center;"></i>' +
'<i class="fa fa-circle-o cm-footer-icns" style="font-size: 15px; width: 15px; font-weight: 500; color: crimson; line-height: 14px; position: absolute; left: 0; text-align: center;"></i>' +
'<i class="fa cm-footer-icns" style="font-size: 8px; font-style: normal; width: 15px; color: black; line-height: 14px; position: absolute; left: 0; text-align: center;">S</i>' +
'</span>' +
'</div>' +
'</div>';
resetContextMenu(contextMenuSettings);
hidePasteMenu();
setTimeout(function () {
if (contextMenuSettings.clipboard === 0 || (contextMenuSettings.clipboard === 1 && document.getElementById('tabRSel') === null))
switchPanelTo('clipboard');
}, 2000);
if (contextMenuSettings.clipboard === 1) switchPanelTo('rsel');
else if (contextMenuSettings.clipboard === 2) switchPanelTo('speed');
if (contextMenuSettings.pin) {
document.getElementById('cmPinMenu').value = true;
document.getElementById('cmPinMenu').classList.remove('toggle-off');
document.getElementById('cmPinClose').classList.remove('toggle-off');
} else {
document.getElementById('cmPinMenu').value = false;
document.getElementById('cmPinMenu').classList.add('toggle-off');
document.getElementById('cmPinClose').classList.add('toggle-off');
}
//======================
// VERSION CHECK
//======================
if (!CMenuVersion.isUpToDate(minVersion)) {
document.getElementById('cmUpdateNote').classList.add('cm-unread');
}
var forumURL = 'https://www.waze.com/forum/viewtopic.php?f=819&t=178371';
updateNotes = 'Hello there! Your friendly right-click WME popup has been recently updated! Within the popup panel, you can now:' +
'</div><div class="cm-panel-section"><ul>' +
'<li>Drag-and-drop speed limit signs to input box</li>' +
'<li>Right-click node A/B to edit speed limit starting from that direction</li>' +
'<li>Add or remove speed limit signs</li>' +
'<li>When WME Speedhelper is not running, the popup will create its own customizable speed limit signs</li>' +
'<li>Some previous bugs were found and squashed</li>' +
'</ul>' +
'<p>Enjoy!</p><p>Coming soonish – A better copy-and-paste menu for segment attributes (and maybe Places... who knows.)</p>';
document.getElementById('cmUpdateNote').onclick = function(e){
e.stopPropagation();
showPopupPanel(minVersion, updateNotes, forumURL);
};
document.getElementById('cmClipboard').onclick = function (e) {
try {
e.stopPropagation();
switchPanelTo('clipboard');
contextMenuSettings.clipboard = 0;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
var selectedStuff = selectedItemsIsSegment();
if (selectedStuff) {
var segInfo = getSegmentProperties(selectedStuff);
populateCopyMenu(segInfo, contextMenuSettings);
} else {
showEmptyPanel('clipboard');
}
hidePasteMenu(false);
} catch (err) {
console.error(err);
};
};
document.getElementById('cmRSel').onclick = function (e) {
try {
e.stopPropagation();
if (document.getElementById('tabRSel') !== null) {
switchPanelTo('rsel');
contextMenuSettings.clipboard = 1;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
var selectedStuff = selectedItemsIsSegment();
if (selectedStuff) {
var segInfo = getSegmentProperties(selectedStuff);
if (document.getElementById('cmRSelAutoAdd')) document.getElementById('cmRSelAutoAdd').style.display = 'block';
populateCopyMenu(segInfo, contextMenuSettings);
} else {
showEmptyPanel('rsel');
}
hidePasteMenu(true);
}
} catch (err) {
console.error(err);
}
};
document.getElementById('cmSpeed').onclick = function (e) {
try {
e.stopPropagation();
switchPanelTo('speed');
contextMenuSettings.clipboard = 2;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
var selectedStuff = selectedItemsIsSegment();
if (selectedStuff) {
SL.menuResetEvent = true;
SL.populateSpeedMenu(contextMenuSettings);
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
} else {
showEmptyPanel('speed');
}
} catch (err) {
console.error(err);
}
};
document.getElementById('map').addEventListener(
'contextmenu',
function (e) {
cmlog([1,0],'------------------------------------------------------------')
cmlog([1,1], 'contextmenu');
//console.info(e);
var selectedStuff = selectionIsSegment(e),
contextMenu = document.getElementById('cmContextMenu');
if (selectedStuff) {
try {
e.stopPropagation();
contextMenu.style.display = 'block';
contextMenu.style.top = e.clientY - 10 + 'px';
contextMenu.style.left = e.clientX + 'px';
contextMenu.classList.remove('cm-drag');
SL.menuResetEvent = true;
setupSegmentContextMenu(e);
contextMenu.style.opacity = 1;
window.addEventListener('keydown', menuShortcutKeys, true);
//console.info('WMECM:','Added initial global hotkey listener upon menu open');
if (document.getElementById('cmPinMenu').value) {
// use a more selective hotkey listener
//console.info('WMECM:','Menu is pinned, so adding selective hotkey listeners too');
contextMenu.addEventListener('mouseenter', addHotkeyListener, false);
contextMenu.addEventListener('mouseleave', removeHotkeyListener, false);
Waze.selectionManager.events.register("selectionchanged", null, setupSegmentContextMenu);
}
} catch (err) { console.error(err); }
} else {
// No segment detected... Decide whether to keep the menu open.
if (document.getElementById('cmPinMenu').value) {
return true;
} else {
contextMenu.style.display = 'none';
return false;
}
}
}, true);
document.getElementById('cmPinMenu').onclick = function (e) {
try {
e.stopPropagation();
if (this.value) { // no pinning
this.value = false;
this.classList.add('toggle-off');
document.getElementById('cmPinClose').classList.add('toggle-off');
// remove drag menu listeners
dragMenuSetup(false);
// closing context menu will remove hotkey listeners & closing contextmenu listeners
// they will be reinstated if appropriate upon reopening the menu
closeContextMenu();
} else { // pin menu
this.value = true;
this.classList.remove('toggle-off');
document.getElementById('cmPinClose').classList.remove('toggle-off');
// remove listeners that close the menu without clicking close
window.removeEventListener('click', closeContextMenu, false);
document.getElementById('toolbar').removeEventListener('mouseenter', closeContextMenu, false);
// Add dragging menu listeners
dragMenuSetup(true);
// use a more selective hotkey listener
//console.info('WMECM:','Switch to menu pinning, so adding selective hotkey listener');
document.getElementById('cmContextMenu').addEventListener('mouseenter', addHotkeyListener, false);
document.getElementById('cmContextMenu').addEventListener('mouseleave', removeHotkeyListener, false);
}
contextMenuSettings.pin = !contextMenuSettings.pin;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
} catch (err) {
console.error(err);
}
};
document.getElementById('cmPinClose').onclick = closeContextMenu;
document.getElementById('cmFooterCaret').addEventListener('click', function (e) {
e.stopPropagation();
if (this.classList.contains('fa-angle-up')) { //switch to top menubar
contextMenuSettings.position = 1;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
adjustContextMenubar(1);
} else if (this.classList.contains('fa-angle-down')) { //switch to bottom menubar
contextMenuSettings.position = 0;
localStorage.WME_ContextMenu = JSON.stringify(contextMenuSettings);
adjustContextMenubar(0);
}
}, false);
} catch (err) {
console.error(err);
}
dragMenuSetup();
var cmWaitCover = document.createElement('div');
cmWaitCover.id = 'cmWaitCover';
cmWaitCover.style.display = 'none';
cmWaitCover.style.position = 'fixed';
cmWaitCover.style.top = 0; cmWaitCover.style.bottom = '25px'; cmWaitCover.style.left = 0; cmWaitCover.style.right = 0;
cmWaitCover.style.background = 'transparent';
cmWaitCover.style.cursor = 'wait';
cmWaitCover.style.zIndex = '5001';
document.body.appendChild(cmWaitCover);
setTimeout(function () {
try {
var rselBtnEls = document.querySelectorAll('#RSconditions button');
for (var b = rselBtnEls.length; b--;) {
rselBtnEls[b].addEventListener('click', function () {
this.classList.remove('btn-info')
}, false);
}
} catch (err) {
console.error(err)
}
}, 1200)
};
var waitCount = 0,
maxWaitCount = 50;
var waitForWaze = function () {
try {
if (document.getElementById('cmContextMenu')) {
return true;
} else if (typeof(Waze) !== "undefined" && Waze.model && Waze.selectionManager &&
Waze.selectionManager.selectedItems &&
Waze.model.segments && Waze.model.cities &&
Waze.map && Waze.map.layers) {
//cmlog([1],'starting...');
setTimeout(initContextMenu, 1000);
//console.info('WMECM:', 'Something may have went wrong... not sure.');
} else if (waitCount++ < maxWaitCount) {
//console.info('waiting...');
setTimeout(waitForWaze, 1000);
} else {
console.error('WMECM:', 'Failed to start');
}
} catch (err) {
console.error('WMECM:', 'Whoa. Major fail. Please let TheLastTaterTot know about this...');
console.error(err);
}
};
waitForWaze();