- // ==UserScript==
- // @name WME HN NavPoints
- // @namespace https://greasyfork.org/users/166843
- // @description Shows navigation points of all house numbers in WME
- // @version 2023.07.20.01
- // @author dBsooner
- // @grant GM_xmlhttpRequest
- // @connect greasyfork.org
- // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
- // @license GPLv3
- // @match http*://*.waze.com/*editor*
- // @exclude http*://*.waze.com/user/editor*
- // @contributionURL https://github.com/WazeDev/Thank-The-Authors
- // ==/UserScript==
-
- /* global _, GM_info, GM_xmlhttpRequest, OpenLayers, W, WazeWrap */
-
- /*
- * Original concept and code for WME HN NavPoints was written by MajkiiTelini. After version 0.6.6, this
- * script is maintained by the WazeDev team. Special thanks is definitely given to MajkiiTelini for his
- * hard work and dedication to the original script.
- *
- */
-
- (function () {
- 'use strict';
-
- // eslint-disable-next-line no-nested-ternary
- const _SCRIPT_SHORT_NAME = `HN NavPoints${(/beta/.test(GM_info.script.name) ? ' β' : /\(DEV\)/i.test(GM_info.script.name) ? ' Ω' : '')}`,
- _SCRIPT_LONG_NAME = GM_info.script.name,
- _IS_ALPHA_VERSION = /[Ω]/.test(_SCRIPT_SHORT_NAME),
- _IS_BETA_VERSION = /[β]/.test(_SCRIPT_SHORT_NAME),
- _PROD_DL_URL = 'https://greasyfork.org/scripts/390565-wme-hn-navpoints/code/WME%20HN%20NavPoints.user.js',
- _FORUM_URL = 'https://www.waze.com/forum/viewtopic.php?f=819&t=269397',
- _SETTINGS_STORE_NAME = 'WMEHNNavPoints',
- _BETA_DL_URL = 'YUhSMGNITTZMeTluY21WaGMzbG1iM0pyTG05eVp5OXpZM0pwY0hSekx6TTVNRFUzTXkxM2JXVXRhRzR0Ym1GMmNHOXBiblJ6TFdKbGRHRXZZMjlrWlM5WFRVVWxNakJJVGlVeU1FNWhkbEJ2YVc1MGN5VXlNQ2hpWlhSaEtTNTFjMlZ5TG1weg==',
- _ALERT_UPDATE = true,
- _SCRIPT_VERSION = GM_info.script.version.toString(),
- _SCRIPT_VERSION_CHANGES = ['CHANGE: Latest WME update compatibility.',
- 'CHANGE: No longer removing HN or lines when first clicking a drag handle or HN input box.'
- ],
- _DEBUG = /[βΩ]/.test(_SCRIPT_SHORT_NAME),
- _LOAD_BEGIN_TIME = performance.now(),
- _elems = {
- div: document.createElement('div'),
- h4: document.createElement('h4'),
- h6: document.createElement('h6'),
- form: document.createElement('form'),
- i: document.createElement('i'),
- label: document.createElement('label'),
- li: document.createElement('li'),
- p: document.createElement('p'),
- svg: document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
- svgText: document.createElementNS('http://www.w3.org/2000/svg', 'text'),
- ul: document.createElement('ul'),
- 'wz-checkbox': document.createElement('wz-checkbox'),
- 'wz-text-input': document.createElement('wz-text-input')
- },
- _spinners = {
- destroyAllHNs: false,
- drawHNs: false,
- processSegs: false
- },
- _timeouts = {
- checkMarkersEvents: {},
- hideTooltip: undefined,
- onWmeReady: undefined,
- saveSettingsToStorage: undefined,
- stripTooltipHTML: undefined
- },
- dec = (s = '') => atob(atob(s));
-
- let _settings = {},
- _scriptActive = false,
- _saveButtonObserver,
- _HNNavPointsLayer,
- _HNNavPointsNumbersLayer,
- _processedSegments = [],
- _segmentsToProcess = [],
- _segmentsToRemove = [],
- _hnNavPointsTooltipDiv,
- _popup = {
- inUse: false,
- hnNumber: -1,
- segmentId: -1
- };
-
- function log(message, data = '') { console.log(`${_SCRIPT_SHORT_NAME}:`, message, data); }
- function logError(message, data = '') { console.error(`${_SCRIPT_SHORT_NAME}:`, new Error(message), data); }
- // function logWarning(message, data = '') { console.warn(`${_SCRIPT_SHORT_NAME}:`, message, data); }
- function logDebug(message, data = '') {
- if (_DEBUG)
- log(message, data);
- }
-
- function $extend(...args) {
- const extended = {},
- deep = Object.prototype.toString.call(args[0]) === '[object Boolean]' ? args[0] : false,
- merge = function (obj) {
- Object.keys(obj).forEach((prop) => {
- if (Object.prototype.hasOwnProperty.call(obj, prop)) {
- if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]')
- extended[prop] = $extend(true, extended[prop], obj[prop]);
- else if ((obj[prop] !== undefined) && (obj[prop] !== null))
- extended[prop] = obj[prop];
- }
- });
- };
- for (let i = deep ? 1 : 0, { length } = args; i < length; i++) {
- if (args[i])
- merge(args[i]);
- }
- return extended;
- }
-
- function createElem(type = '', attrs = {}, eventListener = []) {
- const el = _elems[type]?.cloneNode(false) || _elems.div.cloneNode(false),
- applyEventListeners = function ([evt, cb]) {
- return this.addEventListener(evt, cb);
- };
- Object.keys(attrs).forEach((attr) => {
- if ((attrs[attr] !== undefined) && (attrs[attr] !== 'undefined') && (attrs[attr] !== null) && (attrs[attr] !== 'null')) {
- if ((attr === 'disabled') || (attr === 'checked') || (attr === 'selected') || (attr === 'textContent') || (attr === 'innerHTML'))
- el[attr] = attrs[attr];
- else
- el.setAttribute(attr, attrs[attr]);
- }
- });
- if (eventListener.length > 0) {
- eventListener.forEach((obj) => {
- Object.entries(obj).map(applyEventListeners.bind(el));
- });
- }
- return el;
- }
-
- async function loadSettingsFromStorage() {
- const defaultSettings = {
- disableBelowZoom: 17,
- enableTooltip: true,
- hnLines: true,
- hnNumbers: true,
- keepHNLayerOnTop: true,
- toggleHNNavPointsShortcut: '',
- toggleHNNavPointsNumbersShortcut: '',
- lastSaved: 0,
- lastVersion: undefined
- },
- loadedSettings = JSON.parse(localStorage.getItem(_SETTINGS_STORE_NAME));
- _settings = $extend(true, {}, defaultSettings, loadedSettings);
- const serverSettings = await WazeWrap.Remote.RetrieveSettings(_SETTINGS_STORE_NAME);
- if (serverSettings?.lastSaved > _settings.lastSaved)
- _settings = $extend(true, _settings, serverSettings);
- if (_settings.disableBelowZoom < 11)
- _settings.disableBelowZoom += 12;
- _timeouts.saveSettingsToStorage = window.setTimeout(saveSettingsToStorage, 5000);
-
- return Promise.resolve();
- }
-
- function saveSettingsToStorage() {
- checkTimeout({ timeout: 'saveSettingsToStorage' });
- if (localStorage) {
- ['toggleHNNavPointsShortcut', 'toggleHNNavPointsNumbersShortcut'].forEach((k) => {
- let keys = '';
- const { shortcut } = W.accelerators.Actions[k];
- if (shortcut) {
- if (shortcut.altKey)
- keys += 'A';
- if (shortcut.shiftKey)
- keys += 'S';
- if (shortcut.ctrlKey)
- keys += 'C';
- if (keys !== '')
- keys += '+';
- if (shortcut.keyCode)
- keys += shortcut.keyCode;
- }
- _settings[k] = keys;
- });
- _settings.lastVersion = _SCRIPT_VERSION;
- _settings.lastSaved = Date.now();
- localStorage.setItem(_SETTINGS_STORE_NAME, JSON.stringify(_settings));
- WazeWrap.Remote.SaveSettings(_SETTINGS_STORE_NAME, _settings);
- logDebug('Settings saved.');
- }
- }
- function showScriptInfoAlert() {
- if (_ALERT_UPDATE && (_SCRIPT_VERSION !== _settings.lastVersion)) {
- const divElemRoot = createElem('div');
- divElemRoot.appendChild(createElem('p', { textContent: 'What\'s New:' }));
- const ulElem = createElem('ul');
- if (_SCRIPT_VERSION_CHANGES.length > 0) {
- for (let idx = 0, { length } = _SCRIPT_VERSION_CHANGES; idx < length; idx++)
- ulElem.appendChild(createElem('li', { innerHTML: _SCRIPT_VERSION_CHANGES[idx] }));
- }
- else {
- ulElem.appendChild(createElem('li', { textContent: 'Nothing major.' }));
- }
- divElemRoot.appendChild(ulElem);
- WazeWrap.Interface.ShowScriptUpdate(_SCRIPT_SHORT_NAME, _SCRIPT_VERSION, divElemRoot.innerHTML, (_IS_BETA_VERSION ? dec(_BETA_DL_URL) : _PROD_DL_URL).replace(/code\/.*\.js/, ''), _FORUM_URL);
- }
- }
-
- function checkTimeout(obj) {
- if (obj.toIndex) {
- if (_timeouts[obj.timeout]?.[obj.toIndex]) {
- window.clearTimeout(_timeouts[obj.timeout][obj.toIndex]);
- delete (_timeouts[obj.timeout][obj.toIndex]);
- }
- }
- else {
- if (_timeouts[obj.timeout])
- window.clearTimeout(_timeouts[obj.timeout]);
- _timeouts[obj.timeout] = undefined;
- }
- }
-
- function doSpinner(spinnerName = '', spin = true) {
- const btn = document.getElementById('hnNPSpinner');
- if (!spin) {
- _spinners[spinnerName] = false;
- if (!Object.values(_spinners).some((a) => a === true)) {
- if (btn) {
- btn.classList.remove('fa-spin');
- document.getElementById('divHnNPSpinner').style.display = 'none';
- }
- else {
- const topBar = document.querySelector('#topbar-container .topbar'),
- divElem = createElem('div', {
- id: 'divHnNPSpinner', title: 'WME HN NavPoints is currently processing house numbers.', style: 'font-size:20px;background:white;float:left;display:none;'
- });
- divElem.appendChild(createElem('i', { id: 'hnNPSpinner', class: 'fa fa-spinner' }));
- topBar.insertBefore(divElem, topBar.firstChild);
- }
- }
- }
- else {
- _spinners[spinnerName] = true;
- if (!btn) {
- _spinners[spinnerName] = true;
- const topBar = document.querySelector('#topbar-container .topbar'),
- divElem = createElem('div', {
- id: 'divHnNPSpinner', title: 'WME HN NavPoints is currently processing house numbers.', style: 'font-size:20px;background:white;float:left;'
- });
- divElem.appendChild(createElem('i', { id: 'hnNPSpinner', class: 'fa fa-spinner fa-spin' }));
- topBar.insertBefore(divElem, topBar.firstChild);
- }
- else if (!btn.classList.contains('fa-spin')) {
- btn.classList.add('fa-spin');
- document.getElementById('divHnNPSpinner').style.display = '';
- }
- }
- }
-
- // eslint-disable-next-line default-param-last
- function processSegmentsToRemove(force = false, segmentsArr) {
- const segmentsToProcess = segmentsArr || _segmentsToRemove;
- if (segmentsToProcess.length > 0) {
- let linesToRemove = [],
- hnsToRemove = [];
- const filterMarkers = function (marker) { return marker?.segmentId === this; },
- processFilterMarkers = (marker) => hnsToRemove.push(marker);
- for (let i = segmentsToProcess.length - 1; i > -1; i--) {
- const segId = segmentsToProcess[i];
- if (!W.model.segments.objects[segId] || force) {
- segmentsToProcess.splice(i, 1);
- linesToRemove = linesToRemove.concat(_HNNavPointsLayer.getFeaturesByAttribute('segmentId', segId));
- if (!_settings.enableTooltip)
- hnsToRemove = hnsToRemove.concat(_HNNavPointsNumbersLayer.getFeaturesByAttribute('segmentId', segId));
- else
- _HNNavPointsNumbersLayer.markers.filter(filterMarkers.bind(segId)).forEach(processFilterMarkers);
- }
- }
- if (linesToRemove.length > 0)
- _HNNavPointsLayer.removeFeatures(linesToRemove);
- if (hnsToRemove.length > 0) {
- if (!_settings.enableTooltip)
- _HNNavPointsNumbersLayer.removeFeatures(hnsToRemove);
- else
- hnsToRemove.forEach((marker) => _HNNavPointsNumbersLayer.removeMarker(marker));
- }
- }
- }
-
- async function hnLayerToggled(checked) {
- _HNNavPointsLayer.setVisibility(checked);
- _settings.hnLines = checked;
- saveSettingsToStorage();
- if (checked) {
- if (!_scriptActive)
- await initBackgroundTasks('enable');
- processSegs('hnLayerToggled', W.model.segments.getByAttributes({ hasHNs: true }));
- }
- else if (!_settings.hnNumbers && _scriptActive) {
- initBackgroundTasks('disable');
- }
- }
-
- async function hnNumbersLayerToggled(checked) {
- _HNNavPointsNumbersLayer.setVisibility(checked);
- _settings.hnNumbers = checked;
- saveSettingsToStorage();
- if (checked) {
- if (!_scriptActive)
- await initBackgroundTasks('enable');
- processSegs('hnNumbersLayerToggled', W.model.segments.getByAttributes({ hasHNs: true }));
- }
- else if (!_settings.hnLines && _scriptActive) {
- initBackgroundTasks('disable');
- }
- }
-
- function observeHNLayer() {
- if (W.editingMediator.attributes.editingHouseNumbers) {
- _segmentsToProcess = W.selectionManager.getSegmentSelection().segments.map((segment) => segment.attributes.id);
- _segmentsToRemove = [];
- }
- else {
- W.model.segmentHouseNumbers.clear();
- processSegmentsToRemove(true, [..._segmentsToProcess]);
- processSegs('exithousenumbers', W.model.segments.getByIds([..._segmentsToProcess]), true);
- _segmentsToProcess = [];
- _segmentsToRemove = [];
- _timeouts.checkMarkersEvents = {};
- }
- _saveButtonObserver.disconnect();
- _saveButtonObserver.observe(document.getElementById('save-button'), {
- childList: false, attributes: true, attributeOldValue: true, characterData: false, characterDataOldValue: false, subtree: false
- });
- }
-
- function removeHNs(objArr) {
- let linesToRemove = [],
- hnsToRemove = [];
- const filterMarkers = function (marker) { return marker?.featureId === this.attributes.id; },
- processFilterMarkers = (marker) => {
- hnsToRemove.push(marker);
- };
- objArr.forEach((hnObj) => {
- linesToRemove = linesToRemove.concat(_HNNavPointsLayer.getFeaturesByAttribute('featureId', hnObj.attributes.id));
- if (!_settings.enableTooltip)
- hnsToRemove = hnsToRemove.concat(_HNNavPointsNumbersLayer.getFeaturesByAttribute('featureId', hnObj.attributes.id));
- else
- _HNNavPointsNumbersLayer.markers.filter(filterMarkers.bind(hnObj)).forEach(processFilterMarkers);
- });
- if (linesToRemove.length > 0)
- _HNNavPointsLayer.removeFeatures(linesToRemove);
- if (hnsToRemove.length > 0) {
- if (!_settings.enableTooltip)
- _HNNavPointsNumbersLayer.removeFeatures(hnsToRemove);
- else
- hnsToRemove.forEach((marker) => _HNNavPointsNumbersLayer.removeMarker(marker));
- }
- }
-
- function drawHNs(houseNumberArr) {
- if (houseNumberArr.length === 0)
- return;
- doSpinner('drawHNs', true);
- let svg,
- svgText,
- hnsToRemove = [],
- linesToRemove = [];
- const lineFeatures = [],
- numberFeatures = [],
- invokeTooltip = _settings.enableTooltip ? (evt) => { showTooltip(evt); } : undefined,
- mapFeatureId = (marker) => marker.featureId;
- if (_settings.enableTooltip) {
- svg = createElem('svg', { xlink: 'http://www.w3.org/1999/xlink', xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 40 14' });
- svgText = createElem('svgText', { 'text-anchor': 'middle', x: '20', y: '10' });
- }
- for (let i = 0, { length } = houseNumberArr; i < length; i++) {
- const hnObj = houseNumberArr[i],
- segmentId = hnObj.getSegmentId(),
- seg = W.model.segments.objects[segmentId];
- if (seg) {
- const featureId = hnObj.getID(),
- markerIdx = _settings.enableTooltip ? _HNNavPointsNumbersLayer.markers.map(mapFeatureId).indexOf(featureId) : undefined,
- // eslint-disable-next-line no-nested-ternary
- hnToRemove = _settings.enableTooltip ? (markerIdx > -1) ? _HNNavPointsNumbersLayer.markers[markerIdx] : [] : _HNNavPointsNumbersLayer.getFeaturesByAttribute('featureId', featureId),
- rtlChar = /[\u0590-\u083F]|[\u08A0-\u08FF]|[\uFB1D-\uFDFF]|[\uFE70-\uFEFF]/mg,
- textDir = (hnObj.getNumber().match(rtlChar) !== null) ? 'rtl' : 'ltr';
- linesToRemove = linesToRemove.concat(_HNNavPointsLayer.getFeaturesByAttribute('featureId', featureId));
- if (hnToRemove.length > 0) {
- if (!_settings.enableTooltip)
- hnsToRemove = hnsToRemove.concat(_HNNavPointsNumbersLayer.getFeaturesByAttribute('featureId', featureId));
- else
- hnsToRemove.push(hnToRemove);
- }
- const p1 = new OpenLayers.Geometry.Point(hnObj.getFractionPoint().x, hnObj.getFractionPoint().y),
- p2 = new OpenLayers.Geometry.Point(hnObj.getGeometry().x, hnObj.getGeometry().y),
- // eslint-disable-next-line no-nested-ternary
- strokeColor = (hnObj.isForced()
- ? (!hnObj.getUpdatedBy()) ? 'red' : 'orange'
- : (!hnObj.getUpdatedBy()) ? 'yellow' : 'white'
- );
- let lineString = new OpenLayers.Geometry.LineString([p1, p2]),
- lineFeature = new OpenLayers.Feature.Vector(
- lineString,
- { segmentId, featureId },
- {
- strokeWidth: 4, strokeColor: 'black', strokeOpacity: 0.5, strokeDashstyle: 'dash', strokeDashArray: '8, 8'
- }
- );
- lineFeatures.push(lineFeature);
- lineString = new OpenLayers.Geometry.LineString([p1, p2]);
- lineFeature = new OpenLayers.Feature.Vector(
- lineString,
- { segmentId, featureId },
- {
- strokeWidth: 2, strokeColor, strokeOpacity: 1, strokeDashstyle: 'dash', strokeDashArray: '8, 8'
- }
- );
- lineFeatures.push(lineFeature);
- if (_settings.enableTooltip) {
- svg.setAttribute('style', `text-shadow:0 0 3px ${strokeColor},0 0 3px ${strokeColor},0 0 3px ${strokeColor},0 0 3px ${strokeColor},0 0 3px ${strokeColor},0 0 3px ${strokeColor};font-size:14px;font-weight:bold;font-family:"Open Sans", "Arial Unicode MS", "sans-serif";direction:${textDir}`);
- svgText.textContent = hnObj.getNumber();
- svg.replaceChildren(svgText);
- const svgIcon = new WazeWrap.Require.Icon(`data:image/svg+xml,${svg.outerHTML}`, { w: 40, h: 18 }),
- markerFeature = new OpenLayers.Marker(new OpenLayers.LonLat(p2.x, p2.y), svgIcon);
- markerFeature.events.register('mouseover', null, invokeTooltip);
- markerFeature.events.register('mouseout', null, hideTooltipDelay);
- markerFeature.featureId = featureId;
- markerFeature.segmentId = segmentId;
- markerFeature.hnNumber = hnObj.getNumber() || '';
- numberFeatures.push(markerFeature);
- }
- else {
- // eslint-disable-next-line new-cap
- numberFeatures.push(new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon.createRegularPolygon(p2, 1, 20), {
- segmentId, featureId, hNumber: hnObj.getNumber(), strokeWidth: 3, Color: strokeColor, textDir
- }));
- }
- }
- }
- if (linesToRemove.length > 0)
- _HNNavPointsLayer.removeFeatures(linesToRemove);
- if (hnsToRemove.length > 0) {
- if (!_settings.enableTooltip)
- _HNNavPointsNumbersLayer.removeFeatures(hnsToRemove);
- else
- hnsToRemove.forEach((marker) => _HNNavPointsNumbersLayer.removeMarker(marker));
- }
- if (lineFeatures.length > 0)
- _HNNavPointsLayer.addFeatures(lineFeatures);
- if (numberFeatures.length > 0) {
- if (!_settings.enableTooltip)
- _HNNavPointsNumbersLayer.addFeatures(numberFeatures);
- else
- numberFeatures.forEach((marker) => _HNNavPointsNumbersLayer.addMarker(marker));
- }
- doSpinner('drawHNs', false);
- }
-
- function destroyAllHNs() {
- doSpinner('destroyAllHNs', true);
- _HNNavPointsLayer.destroyFeatures();
- if (_settings.enableTooltip)
- _HNNavPointsNumbersLayer.clearMarkers();
- else
- _HNNavPointsNumbersLayer.destroyFeatures();
- _processedSegments = [];
- doSpinner('destroyAllHNs', false);
- Promise.resolve();
- }
-
- function processSegs(action, arrSegObjs, processAll = false, retry = 0) {
- /* As of 2020.06.08 (sometime before this date) updatedOn does not get updated when updating house numbers. Looking for a new
- * way to track which segments have been updated most recently to prevent a total refresh of HNs after an event.
- * Changed to using a global to keep track of segmentIds touched during HN edit mode.
- */
- if ((action === 'settingChanged') && (W.map.getZoom() < _settings.disableBelowZoom)) {
- destroyAllHNs();
- return;
- }
- if (!arrSegObjs || (arrSegObjs.length === 0) || (W.map.getZoom() < _settings.disableBelowZoom) || preventProcess())
- return;
- doSpinner('processSegs', true);
- const eg = W.map.getExtent().toGeometry(),
- findObjIndex = (array, fldName, value) => array.map((a) => a[fldName]).indexOf(value),
- processError = (err, chunk) => {
- logDebug(`Retry: ${retry}`);
- if (retry < 5)
- processSegs(action, chunk, true, ++retry);
- else
- logError(`Get HNs for ${chunk.length} segments failed. Code: ${err.status} - Text: ${err.responseText}`);
- },
- processJSON = (jsonData) => {
- if ((jsonData?.error === undefined) && (typeof jsonData?.segmentHouseNumbers?.objects !== 'undefined'))
- drawHNs(jsonData.segmentHouseNumbers.objects);
- },
- mapHouseNumbers = (segObj) => segObj.getID(),
- invokeProcessError = function (err) { return processError(err, this); };
- if ((action === 'objectsremoved')) {
- if (arrSegObjs?.length > 0) {
- const removedSegIds = [];
- let hnNavPointsToRemove = [],
- hnNavPointsNumbersToRemove = [];
- arrSegObjs.forEach((segObj) => {
- const segmentId = segObj.getID();
- if (!eg.intersects(segObj.geometry) && (segmentId > 0)) {
- hnNavPointsToRemove = hnNavPointsToRemove.concat(_HNNavPointsLayer.getFeaturesByAttribute('segmentId', segmentId));
- if (!_settings.enableTooltip)
- hnNavPointsNumbersToRemove = hnNavPointsNumbersToRemove.concat(_HNNavPointsNumbersLayer.getFeaturesByAttribute('segmentId', segmentId));
- else
- removedSegIds.push(segmentId);
- const segIdx = findObjIndex(_processedSegments, 'segId', segmentId);
- if (segIdx > -1)
- _processedSegments.splice(segIdx, 1);
- }
- });
- if (hnNavPointsToRemove.length > 0)
- _HNNavPointsLayer.removeFeatures(hnNavPointsToRemove);
- if (hnNavPointsNumbersToRemove.length > 0)
- _HNNavPointsNumbersLayer.removeFeatures(hnNavPointsNumbersToRemove);
- if (removedSegIds.length > 0) {
- _HNNavPointsNumbersLayer.markers.filter((marker) => removedSegIds.includes(marker.segmentId)).forEach((marker) => {
- _HNNavPointsNumbersLayer.removeMarker(marker);
- });
- }
- }
- }
- else { // action = 'objectsadded', 'zoomend', 'init', 'exithousenumbers', 'hnLayerToggled', 'hnNumbersLayerToggled', 'settingChanged', 'afterSave', 'afterclearactions'
- let i = arrSegObjs.length;
- while (i--) {
- if (arrSegObjs[i].getID() < 0) {
- arrSegObjs.splice(i, 1);
- }
- else {
- const segIdx = findObjIndex(_processedSegments, 'segId', arrSegObjs[i].getID());
- if (segIdx > -1) {
- if (arrSegObjs[i].getUpdatedOn() > _processedSegments[segIdx].updatedOn)
- _processedSegments[segIdx].updatedOn = arrSegObjs[i].getUpdatedOn();
- else if (!processAll)
- arrSegObjs.splice(i, 1);
- }
- else {
- _processedSegments.push({ segId: arrSegObjs[i].getID(), updatedOn: arrSegObjs[i].getUpdatedOn() });
- }
- }
- }
- while (arrSegObjs.length > 0) {
- let chunk;
- if (retry === 1)
- chunk = arrSegObjs.splice(0, 250);
- else if (retry === 2)
- chunk = arrSegObjs.splice(0, 125);
- else if (retry === 3)
- chunk = arrSegObjs.splice(0, 100);
- else if (retry === 4)
- chunk = arrSegObjs.splice(0, 50);
- else
- chunk = arrSegObjs.splice(0, 500);
- try {
- W.controller.descartesClient.getHouseNumbers(chunk.map(mapHouseNumbers)).then(processJSON).catch(invokeProcessError.bind(chunk));
- }
- catch (error) {
- processError(error, [...chunk]);
- }
- }
- }
- doSpinner('processSegs', false);
- }
-
- function preventProcess() {
- if (!_settings.hnLines && !_settings.hnNumbers) {
- if (_scriptActive)
- initBackgroundTasks('disable');
- destroyAllHNs();
- return true;
- }
- if (W.map.getZoom() < _settings.disableBelowZoom) {
- destroyAllHNs();
- return true;
- }
- return false;
- }
-
- function segmentsEvent(evt) {
- if (!evt || preventProcess())
- return;
- if ((this.action === 'objectssynced') || (this.action === 'objectsremoved'))
- processSegmentsToRemove();
- if (this.action === 'objectschanged-id') {
- const oldSegmentId = evt.oldID,
- newSegmentID = evt.newID;
- _HNNavPointsLayer.getFeaturesByAttribute('segmentId', oldSegmentId).forEach((feature) => { feature.attributes.segmentId = newSegmentID; });
- if (_settings.enableTooltip)
- _HNNavPointsNumbersLayer.markers.filter((marker) => marker.segmentId === oldSegmentId).forEach((marker) => { marker.segmentId = newSegmentID; });
- else
- _HNNavPointsNumbersLayer.getFeaturesByAttribute('segmentId', oldSegmentId).forEach((feature) => { feature.attributes.segmentId = newSegmentID; });
- }
- else if (this.action === 'objects-state-deleted') {
- evt.forEach((obj) => {
- if (!_segmentsToRemove.includes(obj.getID()))
- _segmentsToRemove.push(obj.getID());
- });
- }
- else {
- processSegs(this.action, evt.filter((seg) => seg.attributes.hasHNs));
- }
- }
-
- function objectsChangedIdHNs(evt) {
- if (!evt || preventProcess())
- return;
- const oldFeatureId = evt.oldID,
- newFeatureId = evt.newID;
- _HNNavPointsLayer.getFeaturesByAttribute('featureId', oldFeatureId).forEach((feature) => { feature.attributes.featureId = newFeatureId; });
- if (_settings.enableTooltip)
- _HNNavPointsNumbersLayer.markers.filter((marker) => marker.featureId === oldFeatureId).forEach((marker) => { marker.featureId = newFeatureId; });
- else
- _HNNavPointsNumbersLayer.getFeaturesByAttribute('featureId', oldFeatureId).forEach((feature) => { feature.attributes.featureId = newFeatureId; });
- }
-
- function objectsChangedHNs(evt) {
- if (!evt || preventProcess())
- return;
- if ((evt.length === 1) && evt[0].getSegmentId() && !_segmentsToProcess.includes(evt[0].getSegmentId()))
- _segmentsToProcess.push(evt[0].getSegmentId());
- }
-
- function objectsStateDeletedHNs(evt) {
- if (!evt || preventProcess())
- return;
- if ((evt.length === 1) && evt[0].getSegmentId() && !_segmentsToProcess.includes(evt[0].getSegmentId()))
- _segmentsToProcess.push(evt[0].getSegmentId());
- removeHNs(evt);
- }
-
- function objectsAddedHNs(evt) {
- if (!evt || preventProcess())
- return;
- if ((evt.length === 1) && evt[0].getSegmentId() && !_segmentsToProcess.includes(evt[0].getSegmentId()))
- _segmentsToProcess.push(evt[0].getSegmentId());
- }
-
- function zoomEndEvent() {
- if (preventProcess())
- return;
- if ((W.map.getZoom() < _settings.disableBelowZoom))
- destroyAllHNs();
- if ((W.map.getZoom() > (_settings.disableBelowZoom - 1)) && (_processedSegments.length === 0))
- processSegs('zoomend', W.model.segments.getByAttributes({ hasHNs: true }), true);
- }
-
- function afterActionsEvent(evt) {
- if (!evt || preventProcess())
- return;
- if ((evt.type === 'afterclearactions') || (evt.type === 'noActions')) {
- processSegmentsToRemove(true, [..._segmentsToProcess]);
- processSegs('afterclearactions', W.model.segments.getByIds([..._segmentsToProcess]), true);
- }
- else if (evt.action?._description?.includes('Deleted house number')) {
- if (evt.type === 'afterundoaction')
- drawHNs([evt.action.object]);
- else
- removeHNs([evt.action.object]);
- }
- else if (evt.action?._description?.includes('Updated house number')) {
- const tempEvt = _.cloneDeep(evt);
- if (evt.type === 'afterundoaction') {
- if (tempEvt.action.newAttributes?.number)
- tempEvt.action.attributes.number = tempEvt.action.newAttributes.number;
- }
- else if (evt.type === 'afteraction') {
- if (tempEvt.action.oldAttributes?.number)
- tempEvt.action.attributes.number = tempEvt.action.oldAttributes.number;
- }
- removeHNs([tempEvt.action.object]);
- drawHNs([evt.action.object]);
- }
- else if (evt.action?._description?.includes('Added house number')) {
- if (evt.type === 'afterundoaction')
- removeHNs([evt.action.houseNumber]);
- else
- drawHNs([evt.action.houseNumber]);
- }
- else if (evt.action?._description?.includes('Moved house number')) {
- drawHNs([evt.action.newHouseNumber]);
- }
- else if (evt.action?.houseNumber) {
- drawHNs((evt.action.newHouseNumber ? [evt.action.newHouseNumber] : [evt.action.houseNumber]));
- }
- }
-
- async function reloadClicked() {
- if (preventProcess() || document.querySelector('wz-button.overlay-button.reload-button').classList.contains('disabled'))
- return;
- await destroyAllHNs();
- processSegs('reload', W.model.segments.getByAttributes({ hasHNs: true }));
- }
-
- function initBackgroundTasks(status) {
- if (status === 'enable') {
- _saveButtonObserver = new MutationObserver((mutationsList) => {
- if ((W.model.actionManager._redoStack.length === 0)
- && mutationsList.some((mutation) => ((mutation.attributeName === 'disabled')
- && (mutation.oldValue === 'true')
- && (mutation.target.disabled === true)))
- ) {
- if (W.editingMediator.attributes.editingHouseNumbers)
- processSegs('afterSave', W.model.segments.getByIds([..._segmentsToProcess]), true);
- else
- processSegmentsToRemove();
- }
- });
- _saveButtonObserver.observe(document.getElementById('save-button'), {
- childList: false, attributes: true, attributeOldValue: true, characterData: false, characterDataOldValue: false, subtree: false
- });
- _saveButtonObserver.observing = true;
- W.accelerators.events.on({ reloadData: destroyAllHNs });
- document.querySelector('wz-button.overlay-button.reload-button').addEventListener('click', reloadClicked);
- W.model.segments.on('objectsadded', segmentsEvent, { action: 'objectsadded' });
- W.model.segments.on('objectsremoved', segmentsEvent, { action: 'objectsremoved' });
- W.model.segments.on('objectssynced', segmentsEvent, { action: 'objectssynced' });
- W.model.segments.on('objects-state-deleted', segmentsEvent, { action: 'objects-state-deleted' });
- W.model.segments.on('objectschanged-id', segmentsEvent, { action: 'objectschanged-id' });
- W.model.segmentHouseNumbers.on({
- objectsadded: objectsAddedHNs,
- objectschanged: objectsChangedHNs,
- 'objectschanged-id': objectsChangedIdHNs,
- 'objects-state-deleted': objectsStateDeletedHNs
- });
- W.editingMediator.on({ 'change:editingHouseNumbers': observeHNLayer });
- W.map.events.on({
- zoomend: zoomEndEvent, addlayer: checkLayerIndex, removelayer: checkLayerIndex
- });
- WazeWrap.Events.register('afterundoaction', this, afterActionsEvent);
- WazeWrap.Events.register('afteraction', this, afterActionsEvent);
- WazeWrap.Events.register('afterclearactions', this, afterActionsEvent);
- _scriptActive = true;
- }
- else if (status === 'disable') {
- _saveButtonObserver = undefined;
- W.accelerators.events.on('reloadData', null, destroyAllHNs);
- document.querySelector('wz-button.overlay-button.reload-button').removeEventListener('click', reloadClicked);
- W.model.segments.off('objectsadded', segmentsEvent, { action: 'objectsadded' });
- W.model.segments.off('objectsremoved', segmentsEvent, { action: 'objectsremoved' });
- W.model.segments.off('objectschanged', segmentsEvent, { action: 'objectschanged' });
- W.model.segments.off('objects-state-deleted', segmentsEvent, { action: 'objects-state-deleted' });
- W.model.segments.off('objectschanged-id', segmentsEvent, { action: 'objectschanged-id' });
- W.model.segmentHouseNumbers.off({
- objectsadded: objectsAddedHNs,
- objectschanged: objectsChangedHNs,
- 'objectschanged-id': objectsChangedIdHNs,
- 'objects-state-deleted': objectsStateDeletedHNs,
- objectsremoved: removeHNs
- });
- W.editingMediator.off({ 'change:editingHouseNumbers': observeHNLayer });
- W.map.events.unregister('zoomend', null, zoomEndEvent);
- W.map.events.unregister('addlayer', null, checkLayerIndex);
- W.map.events.unregister('removelayer', null, checkLayerIndex);
- WazeWrap.Events.unregister('afterundoaction', this, afterActionsEvent);
- WazeWrap.Events.unregister('afteraction', this, afterActionsEvent);
- _scriptActive = false;
- }
- return Promise.resolve();
- }
-
- function enterHNEditMode(segment, moveMap) {
- if (segment) {
- if (moveMap)
- W.map.setCenter({ lon: segment.getCenter().x, lat: segment.getCenter().y }, W.map.getZoom());
- W.selectionManager.setSelectedModels(segment);
- document.querySelector('#segment-edit-general .edit-house-numbers').dispatchEvent(new MouseEvent('click', { bubbles: true }));
- }
- }
-
- function showTooltip(evt) {
- if ((W.map.getZoom() < 16) || W.editingMediator.attributes.editingHouseNumbers || !_settings.enableTooltip)
- return;
- if (evt?.object?.featureId) {
- checkTooltip();
- let moveMap = false;
- const { segmentId, hnNumber } = evt.object;
- if (_popup.inUse && (_popup.hnNumber === hnNumber) && (_popup.segmentId === segmentId))
- return;
- const segment = W.model.segments.getObjectById(segmentId),
- street = W.model.streets.getObjectById(segment.attributes.primaryStreetID),
- popupPixel = W.map.getPixelFromLonLat(evt.object.lonlat),
- divElemRoot = createElem('div', {
- id: 'hnNavPointsTooltipDiv-tooltip',
- class: 'tippy-box',
- 'data-state': 'hidden',
- tabindex: '-1',
- 'data-theme': 'light-border',
- 'data-animation': 'fade',
- role: 'tooltip',
- 'data-placement': 'top',
- style: 'max-width: 350px; transition-duration:300ms;'
- }),
- invokeEnterHNEditMode = () => enterHNEditMode(segment, moveMap),
- divElemRootDivDiv = createElem('div', { class: 'house-number-marker-tooltip' });
- divElemRootDivDiv.appendChild(createElem('div', { class: 'title', dir: 'auto', textContent: `${hnNumber} ${(street ? street.name : '')}` }));
- divElemRootDivDiv.appendChild(createElem('div', {
- id: 'hnNavPointsTooltipDiv-edit', class: 'edit-button fa fa-pencil', style: segment.canEditHouseNumbers() ? '' : 'display:none;'
- }, [{ click: invokeEnterHNEditMode }]));
- const divElemRootDiv = createElem('div', {
- id: 'hnNavPointsTooltipDiv-content', class: 'tippy-content', 'data-state': 'hidden', style: 'transition-duration: 300ms;'
- });
- divElemRootDiv.appendChild(divElemRootDivDiv);
- divElemRoot.appendChild(divElemRootDiv);
- divElemRoot.appendChild(createElem('div', {
- id: 'hnNavPointsTooltipDiv-arrow', class: 'tippy-arrow', style: 'position: absolute; left: 0px;'
- }));
- _hnNavPointsTooltipDiv.replaceChildren(divElemRoot);
- popupPixel.origX = popupPixel.x;
- const popupWidthHalf = (_hnNavPointsTooltipDiv.clientWidth / 2);
- let arrowOffset = (popupWidthHalf - 15),
- dataPlacement = 'top';
- popupPixel.x = ((popupPixel.x - popupWidthHalf + 5) > 0) ? (popupPixel.x - popupWidthHalf + 5) : 10;
- if (popupPixel.x === 10)
- arrowOffset = popupPixel.origX - 22;
- if ((popupPixel.x + (popupWidthHalf * 2)) > W.map.getEl()[0].clientWidth) {
- popupPixel.x = (popupPixel.origX - _hnNavPointsTooltipDiv.clientWidth + 8);
- arrowOffset = (_hnNavPointsTooltipDiv.clientWidth - 30);
- moveMap = true;
- }
- if (popupPixel.y - [..._hnNavPointsTooltipDiv.children].reduce((height, elem) => height + elem.getBoundingClientRect().height, 0) < 0) {
- popupPixel.y += 14;
- dataPlacement = 'bottom';
- }
- else {
- popupPixel.y -= ([..._hnNavPointsTooltipDiv.children].reduce((height, elem) => height + elem.getBoundingClientRect().height, 0) + 14);
- }
- _hnNavPointsTooltipDiv.style.transform = `translate(${Math.round(popupPixel.x)}px, ${Math.round(popupPixel.y)}px)`;
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-arrow').style.transform = `translate(${Math.max(0, Math.round(arrowOffset))}px, 0px)`;
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-tooltip').setAttribute('data-placement', dataPlacement);
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-tooltip').setAttribute('data-state', 'visible');
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-content').setAttribute('data-state', 'visible');
- _popup = { segmentId, hNumber: hnNumber, inUse: true };
- }
- }
-
- function stripTooltipHTML() {
- checkTimeout({ timeout: 'stripTooltipHTML' });
- _hnNavPointsTooltipDiv.replaceChildren();
- _popup = { segmentId: -1, hnNumber: -1, inUse: false };
- }
-
- function hideTooltip() {
- checkTimeout({ timeout: 'hideTooltip' });
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-content')?.setAttribute('data-state', 'hidden');
- _hnNavPointsTooltipDiv.querySelector('#hnNavPointsTooltipDiv-tooltip')?.setAttribute('data-state', 'hidden');
- _timeouts.stripTooltipHTML = window.setTimeout(stripTooltipHTML, 400);
- }
-
- function hideTooltipDelay(evt) {
- if (!evt)
- return;
- checkTimeout({ timeout: 'hideTooltip' });
- const parentsArr = evt.toElement?.offsetParent ? [evt.toElement.offsetParent, evt.toElement.offsetParent.offSetParent] : [];
- if (evt.toElement && (parentsArr.includes(_HNNavPointsNumbersLayer?.div) || parentsArr.includes(_hnNavPointsTooltipDiv)))
- return;
- _timeouts.hideTooltip = window.setTimeout(hideTooltip, 100, evt);
- }
-
- function checkTooltip() {
- checkTimeout({ timeout: 'hideTooltip' });
- }
-
- function checkLayerIndex() {
- const layerIdx = W.map.layers.map((a) => a.uniqueName).indexOf('__HNNavPointsNumbersLayer');
- let properIdx;
- if (_settings.keepHNLayerOnTop) {
- const layersIndexes = [],
- layersLoaded = W.map.layers.map((a) => a.uniqueName);
- ['wmeGISLayersDefault', '__HNNavPointsLayer'].forEach((layerUniqueName) => {
- if (layersLoaded.indexOf(layerUniqueName) > 0)
- layersIndexes.push(layersLoaded.indexOf(layerUniqueName));
- });
- properIdx = (Math.max(...layersIndexes) + 1);
- }
- else {
- properIdx = (W.map.layers.map((a) => a.uniqueName).indexOf('__HNNavPointsLayer') + 1);
- }
- if (layerIdx !== properIdx) {
- W.map.layers.splice(properIdx, 0, W.map.layers.splice(layerIdx, 1)[0]);
- W.map.getOLMap().resetLayersZIndex();
- }
- }
-
- function checkHnNavpointsVersion() {
- if (_IS_ALPHA_VERSION)
- return;
- let updateMonitor;
- try {
- updateMonitor = new WazeWrap.Alerts.ScriptUpdateMonitor(_SCRIPT_LONG_NAME, _SCRIPT_VERSION, (_IS_BETA_VERSION ? dec(_BETA_DL_URL) : _PROD_DL_URL), GM_xmlhttpRequest);
- updateMonitor.start();
- }
- catch (err) {
- logError('Upgrade version check:', err);
- }
- }
-
- async function onWazeWrapReady() {
- log('Initializing.');
- checkHnNavpointsVersion();
- const navPointsNumbersLayersOptions = {
- displayInLayerSwitcher: true,
- uniqueName: '__HNNavPointsNumbersLayer',
- selectable: true,
- labelSelect: true,
- rendererOptions: { zIndexing: true },
- styleMap: new OpenLayers.StyleMap({
- default: new OpenLayers.Style({
- strokeColor: '${Color}',
- strokeOpacity: 1,
- strokeWidth: 3,
- fillColor: '${Color}',
- fillOpacity: 0.5,
- pointerEvents: 'visiblePainted',
- label: '${hNumber}',
- fontSize: '12px',
- fontFamily: 'Rubik, Boing-light, sans-serif;',
- fontWeight: 'bold',
- direction: '${textDir}',
- labelOutlineColor: '${Color}',
- labelOutlineWidth: 3,
- labelSelect: true
- })
- })
- },
- handleCheckboxToggle = function () {
- const settingName = this.id.substring(14);
- if (settingName === 'enableTooltip') {
- if (!this.checked)
- _HNNavPointsNumbersLayer.clearMarkers();
- else
- _HNNavPointsNumbersLayer.destroyFeatures();
- W.map.removeLayer(_HNNavPointsNumbersLayer);
- if (this.checked)
- _HNNavPointsNumbersLayer = new OpenLayers.Layer.Markers('HN NavPoints Numbers Layer', navPointsNumbersLayersOptions);
- else
- _HNNavPointsNumbersLayer = new OpenLayers.Layer.Vector('HN NavPoints Numbers Layer', navPointsNumbersLayersOptions);
- W.map.addLayer(_HNNavPointsNumbersLayer);
- _HNNavPointsNumbersLayer.setVisibility(_settings.hnNumbers);
- }
- _settings[settingName] = this.checked;
- if (settingName === 'keepHNLayerOnTop')
- checkLayerIndex();
- saveSettingsToStorage();
- if ((settingName === 'enableTooltip') && (W.map.getZoom() > (_settings.disableBelowZoom - 1)) && (_settings.hnLines || _settings.hnNumbers))
- processSegs('settingChanged', W.model.segments.getByAttributes({ hasHNs: true }), true, 0);
- },
- handleTextboxChange = function () {
- const newVal = Math.min(22, Math.max(16, +this.value));
- if ((newVal !== _settings.disableBelowZoom) || (+this.value !== newVal)) {
- if (newVal !== +this.value)
- this.value = newVal;
- _settings.disableBelowZoom = newVal;
- saveSettingsToStorage();
- if ((W.map.getZoom() < newVal) && (_settings.hnLines || _settings.hnNumbers))
- processSegs('settingChanged', null, true, 0);
- else if (_settings.hnLines || _settings.hnNumbers)
- processSegs('settingChanged', W.model.segments.getByAttributes({ hasHNs: true }), true, 0);
- }
- },
- buildCheckbox = (id = '', textContent = '', checked = true, title = '', disabled = false) => createElem('wz-checkbox', {
- id, title, disabled, checked, textContent
- }, [{ change: handleCheckboxToggle }]),
- buildTextBox = (id = '', label = '', value = '', placeholder = '', maxlength = 0, autocomplete = 'off', title = '', disabled = false) => createElem('wz-text-input', {
- id, label, value, placeholder, maxlength, autocomplete, title, disabled
- }, [{ change: handleTextboxChange }]),
- toggleHNNavPoints = () => document.getElementById('layer-switcher-item_hn_navpoints').dispatchEvent(new MouseEvent('click', { bubbles: true })),
- toggleHNNavPointsNumbers = () => document.getElementById('layer-switcher-item_hn_navpoints_numbers').dispatchEvent(new MouseEvent('click', { bubbles: true }));
- await loadSettingsFromStorage();
- WazeWrap.Interface.AddLayerCheckbox('display', 'HN NavPoints', _settings.hnLines, hnLayerToggled);
- WazeWrap.Interface.AddLayerCheckbox('display', 'HN NavPoints Numbers', _settings.hnNumbers, hnNumbersLayerToggled);
-
- _HNNavPointsLayer = new OpenLayers.Layer.Vector('HN NavPoints Layer', {
- displayInLayerSwitcher: true,
- uniqueName: '__HNNavPointsLayer'
- });
- _HNNavPointsNumbersLayer = _settings.enableTooltip
- ? new OpenLayers.Layer.Markers('HN NavPoints Numbers Layer', navPointsNumbersLayersOptions)
- : new OpenLayers.Layer.Vector('HN NavPoints Numbers Layer', navPointsNumbersLayersOptions);
- W.map.addLayers([_HNNavPointsLayer, _HNNavPointsNumbersLayer]);
- _HNNavPointsLayer.setVisibility(_settings.hnLines);
- _HNNavPointsNumbersLayer.setVisibility(_settings.hnNumbers);
- window.addEventListener('beforeunload', saveSettingsToStorage, false);
- new WazeWrap.Interface.Shortcut(
- 'toggleHNNavPointsShortcut',
- 'Toggle HN NavPoints layer',
- 'layers',
- 'layersToggleHNNavPoints',
- _settings.toggleHNNavPointsShortcut,
- toggleHNNavPoints,
- null
- ).add();
- new WazeWrap.Interface.Shortcut(
- 'toggleHNNavPointsNumbersShortcut',
- 'Toggle HN NavPoints Numbers layer',
- 'layers',
- 'layersToggleHNNavPointsNumbers',
- _settings.toggleHNNavPointsNumbersShortcut,
- toggleHNNavPointsNumbers,
- null
- ).add();
- const { tabLabel, tabPane } = W.userscripts.registerSidebarTab('HN-NavPoints');
- tabLabel.appendChild(createElem('i', { class: 'w-icon w-icon-location', style: 'font-size:15px;padding-top:4px;' }));
- tabLabel.title = _SCRIPT_SHORT_NAME;
- const docFrags = document.createDocumentFragment();
- docFrags.appendChild(createElem('h4', { style: 'font-weight:bold;', textContent: _SCRIPT_LONG_NAME }));
- docFrags.appendChild(createElem('h6', { style: 'margin-top:0px;', textContent: _SCRIPT_VERSION }));
- let divElemRoot = createElem('div', { class: 'form-group' });
- divElemRoot.appendChild(buildTextBox(
- 'HNNavPoints_disableBelowZoom',
- 'Disable when zoom level is (<) less than:',
- _settings.disableBelowZoom,
- '',
- 2,
- 'off',
- 'Disable NavPoints and house numbers when zoom level is less than specified number.\r\nMinimum: 16\r\nDefault: 17',
- false
- ));
- divElemRoot.appendChild(buildCheckbox(
- 'HNNavPoints_cbenableTooltip',
- 'Enable tooltip',
- _settings.enableTooltip,
- 'Enable tooltip when mousing over house numbers.\r\nWarning: This may cause performance issues.',
- false
- ));
- divElemRoot.appendChild(buildCheckbox('HNNavPoints_cbkeepHNLayerOnTop', 'Keep HN layer on top', _settings.keepHNLayerOnTop, 'Keep house numbers layer on top of all other layers.', false));
- const formElem = createElem('form', { class: 'attributes-form side-panel-section' });
- formElem.appendChild(divElemRoot);
- docFrags.appendChild(formElem);
- docFrags.appendChild(createElem('label', { class: 'control-label', textContent: 'Color legend' }));
- divElemRoot = createElem('div', { style: 'margin:0 10px 0 10px; width:130px; text-align:center; font-size:12px; background:black; font-weight:600;' });
- divElemRoot.appendChild(createElem('div', {
- style: 'text-shadow:0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white,0 0 3px white;', textContent: 'Touched'
- }));
- divElemRoot.appendChild(createElem('div', {
- style: 'text-shadow:0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange,0 0 3px orange;',
- textContent: 'Touched forced'
- }));
- divElemRoot.appendChild(createElem('div', {
- style: 'text-shadow:0 0 3px yellow,0 0 3px yellow,0 0 3px yellow, 0 0 3px yellow,0 0 3px yellow,0 0 3px yellow,0 0 3px yellow,0 0 3px yellow,0 0 3px yellow,0 0 3px yellow;',
- textContent: 'Untouched'
- }));
- divElemRoot.appendChild(createElem('div', {
- style: 'text-shadow:0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red,0 0 3px red;', textContent: 'Untouched forced'
- }));
- docFrags.appendChild(divElemRoot);
- tabPane.appendChild(docFrags);
- tabPane.id = 'sidepanel-hn-navpoints';
- await W.userscripts.waitForElementConnected(tabPane);
- if (!_hnNavPointsTooltipDiv) {
- _hnNavPointsTooltipDiv = createElem('div', {
- id: 'hnNavPointsTooltipDiv',
- style: 'z-index:9999; visibility:visible; position:absolute; inset: auto auto 0px 0px; margin: 0px; top: 0px; left: 0px;',
- 'data-tippy-root': false
- }, [{ mouseenter: checkTooltip }, { mouseleave: hideTooltipDelay }]);
- W.map.getEl()[0].appendChild(_hnNavPointsTooltipDiv);
- }
- await initBackgroundTasks('enable');
- checkLayerIndex();
- log(`Fully initialized in ${Math.round(performance.now() - _LOAD_BEGIN_TIME)} ms.`);
- showScriptInfoAlert();
- if (_scriptActive)
- processSegs('init', W.model.segments.getByAttributes({ hasHNs: true }));
- setTimeout(saveSettingsToStorage, 10000);
- }
-
- function onWmeReady(tries = 1) {
- if (typeof tries === 'object')
- tries = 1;
- checkTimeout({ timeout: 'onWmeReady' });
- if (WazeWrap?.Ready) {
- logDebug('WazeWrap is ready. Proceeding with initialization.');
- onWazeWrapReady();
- }
- else if (tries < 1000) {
- logDebug(`WazeWrap is not in Ready state. Retrying ${tries} of 1000.`);
- _timeouts.onWmeReady = window.setTimeout(onWmeReady, 200, ++tries);
- }
- else {
- logError(new Error('onWmeReady timed out waiting for WazeWrap Ready state.'));
- }
- }
-
- function onWmeInitialized() {
- if (W.userscripts?.state?.isReady) {
- logDebug('W is ready and already in "wme-ready" state. Proceeding with initialization.');
- onWmeReady(1);
- }
- else {
- logDebug('W is ready, but state is not "wme-ready". Adding event listener.');
- document.addEventListener('wme-ready', onWmeReady, { once: true });
- }
- }
-
- function bootstrap() {
- if (!W) {
- logDebug('W is not available. Adding event listener.');
- document.addEventListener('wme-initialized', onWmeInitialized, { once: true });
- }
- else {
- onWmeInitialized();
- }
- }
-
- bootstrap();
- }
- )();