您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Utility to manage RTC
// ==UserScript== // @name WME RTC Manager // @description Utility to manage RTC // @namespace [email protected] // @grant none // @grant GM_info // @version 0.0.2 // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/ // @exclude https://www.waze.com/user/*editor/* // @exclude https://www.waze.com/*/user/*editor/* // @author GyllieGyllie // @license MIT/BSD/X11 // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js // ==/UserScript== /* Changelog */ /* global W */ /* global I18n */ /* global $ */ const ScriptName = GM_info.script.name; const ScriptVersion = GM_info.script.version; let ChangeLog = "RTC Manager has been updated to " + ScriptVersion + "<br />"; ChangeLog = ChangeLog + "<br /><b>New: </b>"; ChangeLog = ChangeLog + "<br />" + "- (0.0.1) Ability to select all linked segments with a matching closure"; ChangeLog = ChangeLog + "<br /><b>Updated: </b>"; ChangeLog = ChangeLog + "<br />" + "- (0.0.2) Fix not all segments being selected in some scenarios"; let wmeSDK; const options = loadOptions(); // Now validate the options are ok validateOptions(options); function log(message) { if (typeof message === 'string') { console.log('RTC Manager: ' + message); } else { console.log('RTC Manager: ', message); } } // the sdk init function will be available after the WME is initialized function WMERTCManager_bootstrap() { if (!document.getElementById('edit-panel') || !wmeSDK.DataModel.Countries.getTopCountry() || !WazeWrap.Ready) { setTimeout(WMERTCManager_bootstrap, 250); return; } if (wmeSDK.State.isReady) { WMERTCManager_init(); } else { wmeSDK.Events.once({ eventName: "wme-ready" }).then(WMERTCManager_init); } } function WMERTCManager_init() { log("Start"); // check for changes in the edit-panel const speedLimitsObserver = new MutationObserver((mutations) => { mutations.forEach(function(mutation) { // Mutation is a NodeList and doesn't support forEach like an array for (let i = 0; i < mutation.addedNodes.length; i++) { const addedNode = mutation.addedNodes[i]; // Only fire up if it's a node if (addedNode.nodeType === Node.ELEMENT_NODE) { if (addedNode.querySelector('div.closures')) { makeListButtons(); } } } makeDetailsButtons(); }); }); speedLimitsObserver.observe(document.getElementById('edit-panel'), { childList: true, subtree: true }); // Catch permalinks //makeSigns(); constructSettings(); displayChangelog(); log("Done"); } // Check if unsafeWindow is availabe, if so use that ('unsafeWindow' in window ? window.unsafeWindow : window).SDK_INITIALIZED.then(() => { // initialize the sdk with your script id and script name wmeSDK = getWmeSdk({scriptId: "wme-rtc-manager", scriptName: "RTC Manager"}); WMERTCManager_bootstrap(); }); function displayChangelog() { if (!WazeWrap.Interface) { setTimeout(displayChangelog, 1000); return; } // Alert the user version updates if (options.lastAnnouncedVersion === ScriptVersion) { log('Version: ' + ScriptVersion); } else { WazeWrap.Interface.ShowScriptUpdate(ScriptName, ScriptVersion, ChangeLog + "<br /><br />", "https://github.com/wazers/rtc-manager"); const updateName = "#wmertcmanager" + ScriptVersion.replaceAll(".", ""); $(updateName + " .WWSUFooter a").text("Github") options.lastAnnouncedVersion = ScriptVersion; saveOptions(options); } } function makeListButtons() { const container = $('div.closures-list'); /*const selectAllButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">Select all</wz-button>'); selectAllButton.on('click', selectAll); container.append(selectAllButton);*/ /*const saveButton = $('<wz-button size="sm" style="width: 100%; margin-top: 10px;">Delete all</wz-button>'); saveButton.on('click', deleteAll); container.append(saveButton);*/ } function makeDetailsButtons() { const container = $('div.closure'); if (!container) { return; } const footer = $('div.closure div.action-buttons'); if ($("#rtcm-detail-all").length > 0) { return; } const selectAllButton = $('<wz-button id="rtcm-detail-all" size="sm"">Select all</wz-button>'); selectAllButton.on('click', selectAll); footer.append(selectAllButton); } function selectAll() { const ids = []; const footerIds = $('div[class^="closureFooterFragmentContainer"] > div > li'); footerIds.each((el) => ids.push($(footerIds[el]).text())); if (ids.length === 0) return; const nearbyClosures = wmeSDK.DataModel.RoadClosures.getAll(); let closure = nearbyClosures.find(closure => ids.indexOf(closure.id) >= 0); const segmentIds = []; const scanned = new Set(); if (closure) { const segment = wmeSDK.DataModel.Segments.getById({ segmentId: closure.segmentId }); // Segment not found if (!segment) { return; } appendSegments(scanned, segmentIds, segment, closure); } wmeSDK.Editing.setSelection({ selection: { ids: segmentIds, objectType: 'segment' } }); } function deleteAll() { const selection = wmeSDK.Editing.getSelection(); if ("segment" !== selection.objectType) { return; } const nearbyClosures = wmeSDK.DataModel.RoadClosures.getAll(); console.log(selection); for (let segmentId of selection.ids) { console.log(segmentId); const segment = wmeSDK.DataModel.Segments.getById({ segmentId: segmentId }); console.log(segment); if (!segment.hasClosures) { continue; } } } function appendSegments(scanned, segmentIds, segment, originalClosure) { // This was already scanned if (scanned.has(segment.id)) { return; } scanned.add(segment.id); const closures = wmeSDK.DataModel.RoadClosures.getAll().filter(rc => rc.segmentId === segment.id); // See if any closure matches for (let closure of closures) { if (originalClosure.description === closure.description && originalClosure.startDate === closure.startDate && originalClosure.endDate === closure.endDate && originalClosure.trafficEventId === closure.trafficEventId) { segmentIds.push(segment.id); break; } } let linkedSegments = wmeSDK.DataModel.Segments.getConnectedSegments({ segmentId: segment.id }); for (let ls of linkedSegments) { appendSegments(scanned, segmentIds, ls, originalClosure); } linkedSegments = wmeSDK.DataModel.Segments.getConnectedSegments({ segmentId: segment.id, reverseDirection: true }); for (let ls of linkedSegments) { appendSegments(scanned, segmentIds, ls, originalClosure); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// //// //// Option Logic //// //////////////////////////////////////////////////////////////////////////////////////////////////////////// function constructSettings() { // -- Set up the tab for the script wmeSDK.Sidebar.registerScriptTab().then(({ tabLabel, tabPane }) => { tabLabel.innerText = 'RTC Manager'; tabLabel.title = 'RTC Manager Settings'; tabPane.innerHTML = '<div id="rtc-manager-settings"></div>'; const scriptContentPane = $('#rtc-manager-settings'); scriptContentPane.append(`<h2 style="margin-top: 0;">RTC Manager</h2>`); scriptContentPane.append(`<span>Current Version: <b>${ScriptVersion}</b></span>`); //addTextNumberSettings(scriptContentPane, '', 'Icon Scale in %', 'iconScale'); //addBooleanSettingsCallback(scriptContentPane, '', 'Enable Clear Sign', 'clearSign', toggleBoolean); }); } function getDefaultOptions() { return { lastAnnouncedVersion: '', } } function loadOptions() { let text = localStorage.getItem("RTC-Manager-Options"); let options; if (text) { options = JSON.parse(text); } else { options = getDefaultOptions(); } return options; } function validateOptions(options) { const defaultOptions = getDefaultOptions(); // Add missing options for (let key in defaultOptions) { if (!(key in options)) { options[key] = defaultOptions[key] } } } function saveOptions(options) { const optionsJson = JSON.stringify(options); localStorage.setItem("RTC-Manager-Options", optionsJson); } function changeText(event) { options[event.target.id] = event.target.value; saveOptions(options); } function addTextNumberSettings(container, title, label, name, step = 1) { const currentValue = options[name]; const textInput = $('<wz-text-input type="number" min="0" max="999" step="' + step + '" id="' + name + '" value="' + currentValue + '"></wz-text-input>'); const optionHtml = $('<div style="margin-top: 10px;"><span Title="' + title + '">' + label + '</span></div>').append(textInput); container.append(optionHtml); textInput.on('change', changeText); } function addBooleanSettingsCallback(container, title, label, name, clickHandler) { const currentValue = options[name]; const checkbox = $('<wz-checkbox id="' + name + '" Title="' + title + '" name="types" disabled="false" checked="' + currentValue + '">' + label + '</wz-checkbox>'); const optionHtml = $('<div class="urcom-option"></div>').append(checkbox); container.append(optionHtml); checkbox.on('click', clickHandler); } function toggleBoolean(event) { options[event.target.id] = event.target.checked; saveOptions(options); }