您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Save/load settings for WME Layers plus scripts
当前为
// ==UserScript== // @name WME Presets // @namespace https://gf.qytechs.cn/en/users/46070 // @description Save/load settings for WME Layers plus scripts // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/editor* // @include https://beta.waze.com/*/editor* // @exclude https://www.waze.com/*user/editor/* // @supportURL https://www.waze.com/forum/viewtopic.php?f=819&t=314906 // @version 1.0 // @grant none // ==/UserScript== /* eslint-env jquery */ /* global W, GM */ // jshint esversion: 6 (function() { // global variables var prefix = "WMEPresets"; var version = '1.0'; var updateMessage = `WME Presets has been updated to version ${version} • First public release!`; var debug = false; if (typeof GM !== 'undefined') { if (GM.info.script.version == '0.0') { //running locally for me as an @require script debug = true; } } var options; var keepOpen = false; function init1(e) { if (e && e.user == null) { return; } logit("Starting init1","debug"); if (typeof W === 'undefined' || typeof W.loginManager === 'undefined') { setTimeout(init1, 200); return; } // go round again if search box isn't there yet if (getById('search') == null) { logit("waiting for search box...","debug"); setTimeout(init1, 200); return; } //pass control to init2 init2(); } function init2() { logit("Starting init2","debug"); loadSettings(); // overload the window unload function to save my settings window.addEventListener("beforeunload", saveSettings, false); if (!W.selectionManager.getSelectedFeatures) { W.selectionManager.getSelectedFeatures = W.selectionManager.getSelectedItems; } //create Button div var div = document.createElement('div'); div.id = "WMEPresetsDiv"; div.classList.add('ItemInactive','toolbar-group','toolbar-submenu'); div.innerHTML = `<i class="toolbar-icon w-icon waze-icon-layers"></i> <menu class="dropdown-menu"></menu>`; div.onmouseenter = myButtonEnter; div.onmouseleave = myButtonLeave; div.children[0].title = `WME Presets v${version}\n\nCTRL+click for Waze Forum topic`; div.children[0].onclick = function (e) { myButtonClicked(e);}; div.children[1].appendChild(MenuNLDiv()); insertNodeAfterNode(div,getById('search')); //Populate loaded NL sets to menu for (let name of options.NL.keys()) { AddNLListItem(name); } //Add menu divs for other scripts div.children[1].appendChild(MenuCHDiv()); for (let name of options.CH.keys()) { AddCHListItem(name); } div.children[1].appendChild(MenuTBHLDiv()); for (let name of options.TBHL.keys()) { AddTBHLListItem(name); } ShowScriptDivs(1); //Add CSS for my elements var styles = ""; styles = '#WMEPresetsDiv div {margin-left: 10px; }'; styles += '#WMEPresetsDiv ul { list-style:none; padding-left:10px; margin-bottom: 0px; border-bottom: 1px solid;}'; styles += '#WMEPresetsDiv li { display: flex; white-space: nowrap; justify-content: space-between; }'; styles += '#WMEPresetsDiv .buttondiv { display: flex; margin-right: 5px; visibility: hidden; }'; styles += '#WMEPresetsDiv .buttondiv-open { visibility: visible; }'; styles += '#WMEPresetsDiv menu { width: auto; min-width: 230px; }'; styles += '#WMEPresetsDiv toolbar-button { line-height: 18px; right: 10px; }'; styles += '#WMEPresetsDiv b { white-space: nowrap; margin-right: 30px; }'; styles += '#WMEPresetsDiv button { height: 22px; margin: -1px 0; padding: 0 1px; border: none; }'; addStyle('WMEPresetsStyle',styles); //check for update if (version != options.oldVersion){ getById('WMEPresetsDiv').children[0].style.color = 'red'; getById('WMEPresetsDiv').children[0].title = ` WME Presets has been updated. Click for more info.`; } logit("Initialisation complete"); // console.timeEnd(prefix + ": initialisation time"); // console.groupEnd(); } function loadSettings() { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (localStorage.WMESSSettings) { //change old settings name to new localStorage.WMEPresets = localStorage.WMESSSettings; localStorage.removeItem('WMESSSettings'); } if (localStorage.WMEPresets) { options = JSON.parse(localStorage.WMEPresets,reviver); } else { options = {}; } if (options.oldVersion == undefined) options.oldVersion = '0.0'; if (options.NL == undefined) options.NL = new Map(); if (options.CH == undefined) options.CH = new Map(); if (options.TBHL == undefined) options.TBHL = new Map(); } function saveSettings() { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (localStorage) { localStorage.WMEPresets = JSON.stringify(options,replacer); } else { logit('Local storage not found','error'); } logit(options,'debug'); } function replacer(key, value) { if(value instanceof Map) { return { dataType: 'Map', value: Array.from(value.entries()), // or with spread: value: [...value] }; } else { return value; } } function reviver(key, value) { if(typeof value === 'object' && value !== null) { if (value.dataType === 'Map') { return new Map(value.value); } } return value; } function myButtonEnter () { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); getById('WMEPresetsDiv').classList.add('open'); } function myButtonLeave () { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (!keepOpen) getById('WMEPresetsDiv').classList.remove('open'); } function myButtonClicked (e) { if (e.altKey && debug) { keepOpen = !keepOpen; return; } if (e.ctrlKey) { window.open('https://www.waze.com/forum/viewtopic.php?f=819&t=314906'); return; } if (version != options.oldVersion) { getById('WMEPresetsDiv').children[0].style.color = ''; getById('WMEPresetsDiv').children[0].title = `WME Presets v${version}\n\nCTRL+click for Waze Forum topic`; options.oldVersion = version; alert(updateMessage); } } // Functions for NL menu function MenuNLDiv() { var div = document.createElement('div'); div.innerHTML = ` <b>WME Layers</b> <i class="toolbar-icon w-icon waze-icon-plus" style="right:5px;margin-top:-4px"></i> <ul id="WMEPresets_NLmenu"></ul>`; div.children[1].onclick = AddNLClicked; return div; } function AddNLClicked () { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newname = prompt ('Enter new set name:'); if (newname == null || newname == '') return; if (options.NL.has(newname)) { alert('Set ' + newname + ' already exists'); return; } AddNLListItem(newname); options.NL.set(newname, JSON.parse(JSON.stringify(W.layerSwitcherController.checkboxState.attributes))); } function AddNLListItem (name) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newli = document.createElement('li'); newli.innerText = name; newli.onclick = function (e) { NLItemClick(name,e);}; newli.appendChild(ButtonDiv(NLItemClick,'NL')); newli.onmouseenter = function (e) { e.target.firstElementChild.classList.add('buttondiv-open');}; newli.onmouseleave = function (e) { e.target.firstElementChild.classList.remove('buttondiv-open');}; getById('WMEPresets_NLmenu').appendChild(newli); } function NLItemClick (name,e) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (e.target.tagName !== 'LI') return; for (var i in options.NL.get(name)) { // logit(i + ' : ' + options.NL.get(name)[i], 'debug'); if (W.layerSwitcherController.getTogglerState(i) !== undefined) { W.layerSwitcherController.setTogglerState(i, options.NL.get(name)[i]); } else { logit('Layers set ' + name + ' contains non-existent layer ' + i,'error'); } } } function ShowScriptDivs (attempt) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + "called, attempts = " + attempt, "debug"); if (attempt == 50) { //stop trying after 10 seconds return; } var scriptcount = 0; if (getById('sidepanel-highlights') !== null) { getById('WMEPresets_MenuCHDiv').style.display = ''; scriptcount++; } if (getById('tb-highlightsContainer') !== null) { getById('WMEPresets_MenuTBHLDiv').style.display = ''; scriptcount++; } if (scriptcount < 2) setTimeout(ShowScriptDivs,200,attempt+1); } //Functions for WMECH menu function MenuCHDiv() { var div = document.createElement('div'); div.id = 'WMEPresets_MenuCHDiv'; div.style.display = 'none'; div.innerHTML = ` <b title="WME Colour Highlights settings">WMECH settings</b> <i class="toolbar-icon w-icon waze-icon-plus" style="right:5px;margin-top:-4px"></i> <ul id="WMEPresets_CHmenu"></ul>`; div.children[1].onclick = AddCHClicked; return div; } function AddCHClicked () { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newname = prompt ('Enter new set name:'); if (newname == null || newname == '') return; if (options.CH.has(newname)) { alert('Set ' + newname + ' already exists'); return; } AddCHListItem(newname); var inputs = getById('sidepanel-highlights').getElementsByTagName('input'); var toSave = []; var item; var i; for (i = 0; i < inputs.length; i++) { item = {}; item.name = inputs[i].id; item.type = inputs[i].type; switch (item.type) { case 'checkbox': item.value = inputs[i].checked; break; case 'number': item.value = inputs[i].value; break; default: item.value = 'unhandled'; } toSave.push(item); } options.CH.set(newname, toSave); } function AddCHListItem (name) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newli = document.createElement('li'); newli.innerText = name; newli.onclick = function (e) { CHItemClick(name,e);}; newli.appendChild(ButtonDiv(CHItemClick,'CH')); newli.onmouseenter = function (e) { e.target.firstElementChild.classList.add('buttondiv-open');}; newli.onmouseleave = function (e) { e.target.firstElementChild.classList.remove('buttondiv-open');}; getById('WMEPresets_CHmenu').appendChild(newli); } function CHItemClick (name,e) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (e.target.tagName !== 'LI') return; var toSet = options.CH.get(name); for (var i=0; i<toSet.length; i++) { if (getById(toSet[i].name) == undefined) { logit('Missing WMECH input ' + getById(toSet[i].name), 'error'); } else { switch (toSet[i].type) { case 'checkbox': getById(toSet[i].name).checked = toSet[i].value; break; case 'number': getById(toSet[i].name).value = toSet[i].value; break; default: //donothing } } } } //Functions for WMETBHL menu function MenuTBHLDiv() { var div = document.createElement('div'); div.id = 'WMEPresets_MenuTBHLDiv'; div.style.display = 'none'; div.innerHTML = ` <b title="WME Toolbox Highlights settings">TB Highlights</b> <i class="toolbar-icon w-icon waze-icon-plus" style="right:5px;margin-top:-4px"></i> <ul id="WMEPresets_TBHLmenu"></ul>`; div.children[1].onclick = AddTBHLClicked; return div; } function AddTBHLClicked () { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newname = prompt ('Enter new set name:'); if (newname == null || newname == '') return; if (options.TBHL.has(newname)) { alert('Set ' + newname + ' already exists'); return; } AddTBHLListItem(newname); var inputs = getById('tb-highlightsContainer').getElementsByTagName('input'); var toSave = []; var item; var i; for (i = 0; i < inputs.length; i++) { item = {}; item.name = inputs[i].id; item.type = inputs[i].type; switch (item.type) { case 'checkbox': item.value = inputs[i].checked; break; case 'color': item.value = inputs[i].value; break; default: item.value = 'unhandled'; } toSave.push(item); } options.TBHL.set(newname, toSave); } function AddTBHLListItem (name) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); var newli = document.createElement('li'); newli.innerText = name; newli.onclick = function (e) { TBHLItemClick(name,e);}; newli.appendChild(ButtonDiv(TBHLItemClick,'TBHL')); newli.onmouseenter = function (e) { e.target.firstElementChild.classList.add('buttondiv-open');}; newli.onmouseleave = function (e) { e.target.firstElementChild.classList.remove('buttondiv-open');}; getById('WMEPresets_TBHLmenu').appendChild(newli); } function TBHLItemClick (name,e) { var fname = arguments.callee.toString().match(/function ([^(]+)/)[1]; logit("function " + fname + " called", "debug"); if (e.target.tagName !== 'LI') return; var toSet = options.TBHL.get(name); var changeEvent = new Event('change'); for (var i=0; i<toSet.length; i++) { if (getById(toSet[i].name) == undefined) { logit('Missing WMETBHL input ' + getById(toSet[i].name), 'error'); } else { switch (toSet[i].type) { case 'checkbox': if (getById(toSet[i].name).checked != toSet[i].value) { getById(toSet[i].name).click(); } break; case 'color': if (getById(toSet[i].name).value != toSet[i].value) { getById(toSet[i].name).value = toSet[i].value; getById(toSet[i].name).dispatchEvent(changeEvent); } break; default: //donothing } } } } //common functions for preset controls function ButtonDiv (func,settingsGroup) { var div = document.createElement('div'); div.classList.add('buttondiv'); var button; button = document.createElement('button'); button.classList.add('fas','fa-pen'); button.title = 'Rename'; button.onclick = function(e) { ItemButtonClicked(func,settingsGroup,e); }; div.appendChild(button); button = document.createElement('button'); button.classList.add('fas','fa-arrow-up'); button.title = 'Move up'; button.onclick = function(e) { ItemButtonClicked(func,settingsGroup,e); }; div.appendChild(button); button = document.createElement('button'); button.classList.add('fas','fa-arrow-down'); button.title = 'Move down'; button.onclick = function(e) { ItemButtonClicked(func,settingsGroup,e); }; div.appendChild(button); button = document.createElement('button'); button.classList.add('fas','fa-times'); button.title = 'Delete'; button.onclick = function(e) { ItemButtonClicked(func,settingsGroup,e); }; div.appendChild(button); // div.onclick = function (e) { func(name,e);}; return div; } function ItemButtonClicked (func,settingsGroup,e) { var newmap = new Map(); var parentli = e.target.parentNode.parentNode; var oldname = parentli.childNodes[0].textContent; if (e.target.classList.contains('fa-pen')) { var newname = prompt('New set name:'); if (options[settingsGroup].has(newname)) { alert('Set "' + newname + '" already exists'); } else if (newname != null && newname != '') { parentli.childNodes[0].textContent = newname; parentli.onclick = function (e) { func(newname,e);}; for (let [key,value] of options[settingsGroup]) { if (key == oldname) { newmap.set(newname, value); } else { newmap.set(key,value); } } options[settingsGroup] = newmap; } } var orderChanged = false; if (e.target.classList.contains('fa-arrow-up')) { if (parentli.previousSibling !== null) { parentli.previousSibling.insertAdjacentElement('beforebegin',parentli); orderChanged = true; } } if (e.target.classList.contains('fa-arrow-down')) { if (parentli.nextSibling !== null) { parentli.nextSibling.insertAdjacentElement('afterend',parentli); orderChanged = true; } } if (orderChanged) { // redo map in new order for (var i = 0; i < parentli.parentNode.children.length; i++) { newmap.set(parentli.parentNode.children[i].innerText,options[settingsGroup].get(parentli.parentNode.children[i].innerText)); } options[settingsGroup] = newmap; } if (e.target.classList.contains('fa-times')) { e.target.parentNode.parentNode.remove(); options[settingsGroup].delete(oldname); } e.target.blur(); } function addStyle(ID, css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } removeStyle(ID); // in case it is already there style = document.createElement('style'); style.innerHTML = css; style.id = ID; head.appendChild(style); } function removeStyle(ID) { var style = document.getElementById(ID); if (style) { style.parentNode.removeChild(style); } } function getById(node) { return document.getElementById(node); } function insertNodeBeforeNode (insertNode, beforeNode) { beforeNode.parentNode.insertBefore(insertNode,beforeNode); } function insertNodeAfterNode (insertNode, afterNode) { insertNodeBeforeNode (insertNode, afterNode); insertNodeBeforeNode (afterNode,insertNode); } function logit(msg, typ) { if (!typ) { console.log(prefix + ": " + msg); } else { switch(typ) { case "error": console.error(prefix + ": " + msg); break; case "warning": console.warn(prefix + ": " + msg); break; case "info": console.info(prefix + ": " + msg); break; case "debug": if (debug) { console.warn(prefix + ": " + msg); } break; default: console.log(prefix + " unknown message type: " + msg); break; } } } // Start it running setTimeout(init1, 200); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址