您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Lists all turn instructions defined within the current map view
// ==UserScript== // @name TISWAS // @namespace http://greasemonkey.chizzum.com // @description Lists all turn instructions defined within the current map view // @include https://*.waze.com/*editor* // @include https://editor-beta.waze.com/* // @include https://beta.waze.com/* // @exclude https://www.waze.com/user/*editor/* // @exclude https://www.waze.com/*/user/*editor/* // @grant none // @version 0.8 // ==/UserScript== /* JSHint Directives */ /* globals W: true */ /* globals trustedTypes: */ /* jshint bitwise: false */ /* jshint eqnull: true */ /* jshint esversion: 11 */ /* jshint undef: true */ /* jshint unused: true */ const TISWAS = { graphEntries: [], ModifyHTML: function(htmlIn) { if(typeof trustedTypes === "undefined") { return htmlIn; } else { const escapeHTMLPolicy = trustedTypes.createPolicy("forceInner", {createHTML: (to_escape) => to_escape}); return escapeHTMLPolicy.createHTML(htmlIn); } }, AddEventListener: function(elm,eventType,eventFn,eventBool) { try { document.getElementById(elm).addEventListener(eventType, eventFn, eventBool); } catch(err) { TISWAS.AddLog('AddEventListener() - '+elm+' not found!'); } }, AddLog: function(logtext) { console.log('TISWAS: '+Date()+' '+logtext); }, RegexContains: function(text, contains) { let retval = false; if(text !== null) { let re = RegExp(contains, 'i'); if(text.search(re) != -1) { retval = true; } } return retval; }, GraphEntry: function(segID, es, rs, t, tts, vi) { this.segID = segID; this.es = es; this.rs = rs; this.t = t; this.tts = tts; this.vi = vi; }, PushGraphEntry: function(e) { for(let i in e) { if(e.hasOwnProperty(i)) { let tg = e[i].turnGuidance; if(tg !== null) { let segID = i; segID = segID.replace("f",""); segID = segID.replace("r",""); let es = []; let rs = []; if(tg.exitSigns !== null) { for(let j = 0; j < tg.exitSigns.length; ++j) { es.push(tg.exitSigns[j]); } } if(tg.roadShields !== null) { for(let j in tg.roadShields) { if(tg.roadShields.hasOwnProperty(j)) { rs.push(tg.roadShields[j]); } } } let entry = new TISWAS.GraphEntry(segID, es, rs, tg.towards, tg.tts, tg.visualInstruction); TISWAS.graphEntries.push(entry); } } } }, SegSelect: function(e) { let segID = e.currentTarget.attributes.tag.value; let segObj = W.model.segments.objects[segID]; let segCenter = segObj.attributes.geometry.getBounds().getCenterLonLat(); W.selectionManager.setSelectedModels(segObj); W.map.setCenter(segCenter); }, ReplaceShieldIDs: function(textIn, rs) { while(textIn.indexOf("$RS") !== -1) { let start = textIn.indexOf("$RS"); let end = textIn.indexOf(" ", start); let rsID = null; if(end === -1) { rsID = parseInt(textIn.slice(start + 4)); } else { rsID = parseInt(textIn.slice(start + 4, end)); } let rsImg = ""; if(rsID !== null) { rsImg = '<img src="https://renderer-row.waze.com/renderer/v1/signs/' + rs[rsID].type + '?text=' + rs[rsID].text + '" height="40px" style="margin-top:-8px;margin-bottom:-8px;">'; if(rs[rsID].direction !== null) { rsImg += rs[rsID].direction; } } if(end === -1) { textIn = textIn.slice(0, start) + rsImg; } else { textIn = textIn.slice(0, start) + rsImg + textIn.slice(end + 1); } } return textIn; }, FormatTI: function(ge, idx, useFilter, contains) { let showTI; if(useFilter === false) { showTI = true; } else { showTI = false; } let innerHTML = '<div style="background-color: yellow;"><i class="fa fa-road" style="scale:150%;;padding-right:10px;"></i><b>' + ge.segID + '</b></div>'; innerHTML += '<div style="padding-left:10px;padding-top:4px;">'; if(ge.es.length !== 0) { innerHTML += '<i class="fa fa-sign-out" style="scale:150%;;padding-right:10px;"></i>'; for(let j = 0; j < ge.es.length; ++j) { innerHTML += '<img src="https://renderer-row.waze.com/renderer/v1/signs/' + ge.es[j].type + '?text=' + ge.es[j].text + '" height="25px" style="padding-right:10px;">'; } innerHTML += '<br>'; } if(ge.vi !== null) { innerHTML += '<i class="fa fa-eye" style="scale:150%;;padding-right:10px;"></i>'; innerHTML += TISWAS.ReplaceShieldIDs(ge.vi, ge.rs); innerHTML += '<br>'; if(useFilter === true) { showTI = showTI || TISWAS.RegexContains(ge.vi, contains); } } if(ge.rs.length > 0) { for(let j = 0; j < ge.rs.length; ++j) { if(useFilter === true) { showTI = showTI || TISWAS.RegexContains(ge.rs[j].text, contains); showTI = showTI || TISWAS.RegexContains(ge.rs[j].direction, contains); } } } if(ge.t !== "") { innerHTML += '<i class="fa fa-reply" style="scale:150%;;padding-right:10px;"></i>'; innerHTML += TISWAS.ReplaceShieldIDs(ge.t, ge.rs); innerHTML += '<br>'; if(useFilter === true) { showTI = showTI || TISWAS.RegexContains(ge.t, contains); } } if(ge.tts !== null) { innerHTML += '<i class="fa fa-comment" style="scale:150%;;padding-right:10px;"></i>'; innerHTML += ge.tts + '<br>'; if(useFilter === true) { showTI = showTI || TISWAS.RegexContains(ge.tts, contains); } } innerHTML += '</div>'; let resHTML = '<div id="_tdiv-' + idx + '" tag="' + ge.segID + '" style="padding:2px; margin:6px; cursor:pointer;'; if(showTI === false) { resHTML += ' display:none;'; } resHTML += '">'; resHTML += innerHTML; resHTML += '</div>'; return resHTML; }, DisplayTIs: function() { let resHTML = ''; let filterEnabled = document.querySelector('#_tisEnableFilter').checked; let filterContains = document.querySelector('#_tisContains').value; for(let i = 0; i < TISWAS.graphEntries.length; ++i) { let ge = TISWAS.graphEntries[i]; resHTML += TISWAS.FormatTI(ge, i, filterEnabled, filterContains); } return resHTML; }, UpdateList: function() { let outPane = document.querySelector('#_tisOutput'); if(outPane !== null) { let resHTML = ''; let nEntries = 0; if(W.map.getZoom() >= 17) { nEntries = TISWAS.graphEntries.length; if(nEntries > 0) { resHTML += TISWAS.DisplayTIs(); } else { resHTML += "No TIs here..."; } } else { resHTML += "TIs only available at zoom 17+"; } outPane.innerHTML = TISWAS.ModifyHTML(resHTML); if(nEntries > 0) { for(let i = 0; i < nEntries; ++i) { let linkID = "_tdiv-" + i; TISWAS.AddEventListener(linkID, "click", TISWAS.SegSelect, true); } } } }, SurfaceTIs: function() { TISWAS.graphEntries = []; if(W.map.getZoom() >= 17) { W.model.turnGraph.reverseAdjacencyList.forEach(TISWAS.PushGraphEntry); } TISWAS.UpdateList(); }, PopulateUI: function() { var iHTML = ''; iHTML += '<div id="_tisControl">'; iHTML += '<i class="fa fa-filter" style="scale:150%;padding-right:10px;"></i><input type="checkbox" id="_tisEnableFilter" /> '; iHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_tisContains">'; iHTML += '</div>'; iHTML += '<div id="_tisOutput" />'; return iHTML; }, Initialise: function() { TISWAS.AddLog("Initialise"); if(document.getElementsByClassName("sandbox").length > 0) { TISWAS.AddLog('WME practice mode detected, script is disabled...'); return; } if(document.location.href.indexOf('user/') !== -1) { TISWAS.AddLog('User profile page detected, script is disabled...'); return; } TISWAS.WaitForW(); }, WaitForW: function() { if(window.W === undefined) { window.setTimeout(TISWAS.WaitForW, 100); return; } if (W.userscripts?.state?.isReady) { TISWAS.AddTab_API(); } else { document.addEventListener("wme-ready", TISWAS.AddTab_API, {once: true}); } }, AddTab_API: async function() { TISWAS.AddLog("Registering with sidepanel..."); let {tabLabel, tabPane} = W.userscripts.registerSidebarTab("TISWAS"); tabLabel.innerText = "TISWAS"; tabPane.innerHTML = TISWAS.ModifyHTML(TISWAS.PopulateUI()); await W.userscripts.waitForElementConnected(tabPane); TISWAS.CompleteUISetup(); }, CompleteUISetup: function() { W.map.events.register("moveend", null, TISWAS.SurfaceTIs); W.map.events.register("zoomend", null, TISWAS.SurfaceTIs); TISWAS.AddEventListener("_tisEnableFilter", "change", TISWAS.UpdateList, true); TISWAS.AddEventListener("_tisContains", "keyup", TISWAS.UpdateList, true); } }; TISWAS.Initialise();