WME Fix UI

Allows alterations to the WME UI to fix things screwed up or ignored by Waze

As of 2016-06-17. See the latest version.

  1. // ==UserScript==
  2. // @name WME Fix UI
  3. // @namespace https://greatest.deepsurf.us/en/users/46070
  4. // @description Allows alterations to the WME UI to fix things screwed up or ignored by Waze
  5. // @include https://www.waze.com/editor/*
  6. // @include https://www.waze.com/*/editor/*
  7. // @include https://editor-beta.waze.com/*
  8. // @exclude https://www.waze.com/user/editor/*
  9. // @supportURL https://www.waze.com/forum/viewtopic.php?f=819&t=191178
  10. // @version 0.10
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. // Thanks to (in no particular order) Bellhouse, Twister-UK, Timbones, Dave2084, Rickzabel, Glodenox
  15.  
  16. (function()
  17. {
  18. // global variables
  19. var wmefu_version = "0.10";
  20. var applyCount = 0;
  21. var wmefuinit = false;
  22. var wmeFUAddon;
  23.  
  24. function createAddon() {
  25. var addon = document.createElement('section');
  26. addon.id = "wmefu-addon";
  27. var section = document.createElement('p');
  28. section.style.paddingTop = "0px";
  29. section.id = "fuContent";
  30. section.innerHTML = '<b>UI Fixes</b><br>';
  31. section.innerHTML += '<input type="checkbox" id="_cbMoveZoomBar" /> ' +
  32. '<span title="Because nobody likes a pointless UI change that breaks your workflow, imposed by idiots who rarely use the editor and don\'t listen to feedback">Move zoom bar to left</span><br>';
  33. section.innerHTML += '<input type="checkbox" id="_cbHideUserInfo" /> ' +
  34. '<span title="Because we can earn points quicker without a massive chunk of space wasted on telling us how many we earnt up to yesterday">Hide user info in the side panel</span><br>';
  35. section.innerHTML += '<input type="checkbox" id="_cbShrinkBlackBar" /> ' +
  36. '<span title="Because we can\'t afford to waste screen space on stuff we didn\'t ask for and don\'t want">Shrink the black bar above the map</span><br>';
  37. section.innerHTML += '<input type="checkbox" id="_cbCompressSegmentTab" /> ' +
  38. '<span title="Because I\'m sick of having to scroll the side panel because of oversized fonts and wasted space">Compress the contents of the side panel</span><br>';
  39. section.innerHTML += '<input type="checkbox" id="_cbRestyleReports" /> ' +
  40. '<span title="Another UI element configured for developers with massive screens instead of normal users">Change formatting for report panels (UR/MP)</span><br>';
  41. section.innerHTML += '<input type="checkbox" id="_cbDisableMapBlocker" /> ' +
  42. '<span title="As if the crappy interface wasn\'t making life hard enough, now they force us to wait for an arbitrary time after every save!">Disable map blocking during/after saving.</span><span title="Use at your own risk. We don\'t know why it\'s there. Maybe there\'s a good reason but Waze can\'t be arsed to tell us what it is." style="font-size: 16px; color: red;">&#9888</span><br>';
  43. section.innerHTML += '<input type="checkbox" id="_cbNarrowSidePanel" /> ' +
  44. '<span title="If you have a netbook, Waze isn\'t interested in your experience. You need every bit of map space you can get - so have a present from me!">Reduce width of the side panel</span><span title="This will definitely interfere with scripts that rely on a fixed width for their tabs." style="font-size: 16px; color: red;">&#9888</span><br>';
  45. section.innerHTML += '<br>';
  46. section.innerHTML += '<b><a href="https://greatest.deepsurf.us/en/scripts/20077-wme-fix-ui" target="_blank"><u>' +
  47. 'WME Fix UI</u></a></b> &nbsp; v' + wmefu_version;
  48.  
  49. addon.appendChild(section);
  50. addon.id = "sidepanel-FixUI";
  51. addon.className = "tab-pane";
  52. return addon
  53. }
  54.  
  55. function addMyTab(model,modeID) {
  56. if (modeID === 0) {
  57. console.log("WMEFU: entering default mode, so creating tab");
  58. var userTabs = getId('user-info');
  59. var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
  60. if (typeof navTabs === "undefined") {
  61. console.log("WMEFU: not logged in - will initialise later");
  62. Waze.loginManager.on("login", initialiseFixUI);
  63. return;
  64. }
  65. var tabContent = getElementsByClassName('tab-content', userTabs)[0];
  66. newtab = document.createElement('li');
  67. newtab.innerHTML = '<a href="#sidepanel-FixUI" data-toggle="tab" title="Fix UI">FU</a>';
  68. navTabs.appendChild(newtab);
  69. tabContent.appendChild(wmeFUAddon);
  70. } else {
  71. console.log("WMEFU: entering event mode, so not initialising");
  72. return;
  73. }
  74. }
  75.  
  76. function initialiseFixUI() {
  77. if (wmefuinit) {
  78. return;
  79. }
  80.  
  81. // go round again if map container isn't there yet
  82. if(!window.Waze.map)
  83. {
  84. window.console.log("WME FixUI: waiting for WME...");
  85. setTimeout(initialiseFixUI, 1000);
  86. return;
  87. }
  88.  
  89. // create tab content
  90. wmeFUAddon = createAddon();
  91.  
  92. // insert the content as a tab
  93. addMyTab(null,0);
  94.  
  95. // recreate my tab when MTE mode is exited
  96. Waze.app.modeController.model.bind('change:mode', addMyTab);
  97.  
  98. // setup event handlers for user actions:
  99. getId('_cbMoveZoomBar').onclick = moveZoomBar;
  100. getId('_cbShrinkBlackBar').onclick = shrinkBlackBar;
  101. getId('_cbHideUserInfo').onclick = hideUserInfo;
  102. getId('_cbCompressSegmentTab').onclick = compressSegmentTab;
  103. getId('_cbRestyleReports').onclick = restyleReports;
  104. getId('_cbDisableMapBlocker').onclick = disableMapBlocker;
  105. getId('_cbNarrowSidePanel').onclick = narrowSidePanel;
  106.  
  107. // restore saved settings
  108. if (localStorage.WMEFixUI) {
  109. console.log("WMEFU: loading options");
  110. options = JSON.parse(localStorage.WMEFixUI);
  111.  
  112. getId('_cbMoveZoomBar').checked = options[1];
  113. getId('_cbShrinkBlackBar').checked = options[2];
  114. getId('_cbHideUserInfo').checked = options[3];
  115. getId('_cbCompressSegmentTab').checked = options[4];
  116. getId('_cbRestyleReports').checked = options[5];
  117. getId('_cbDisableMapBlocker').checked = options[6];
  118. getId('_cbNarrowSidePanel').checked = options[7];
  119. } else {
  120. // default values if option isn't stored
  121. getId('_cbMoveZoomBar').checked = true;
  122. getId('_cbShrinkBlackBar').checked = true;
  123. getId('_cbHideUserInfo').checked = true;
  124. getId('_cbCompressSegmentTab').checked = true;
  125. getId('_cbRestyleReports').checked = true;
  126. getId('_cbDisableMapBlocker').checked = false;
  127. getId('_cbNarrowSidePanel').checked = false;
  128. }
  129.  
  130. if (Waze.loginManager.user.userName == 'iainhouse') {
  131. // Adds an extra checkbox so I can test segment panel changes easily
  132. var brand = getId('brand');
  133. extraCBSection = document.createElement('p');
  134. extraCBSection.innerHTML = '<input type="checkbox" id="_cbextraCBSection" />';
  135. brand.appendChild(extraCBSection);
  136. getId('_cbextraCBSection').onclick = FALSEcompressSegmentTab;
  137. _cbextraCBSection.checked = _cbCompressSegmentTab.checked;
  138. }
  139.  
  140. // overload the WME exit function
  141. saveOptions = function() {
  142. if (localStorage) {
  143. console.log("WMEFU: saving options");
  144. var options = [];
  145.  
  146. // preserve previous options which may get lost after logout
  147. if (localStorage.WMEFixUI)
  148. options = JSON.parse(localStorage.WMEFixUI);
  149.  
  150. options[1] = getId('_cbMoveZoomBar').checked;
  151. options[2] = getId('_cbShrinkBlackBar').checked;
  152. options[3] = getId('_cbHideUserInfo').checked;
  153. options[4] = getId('_cbCompressSegmentTab').checked;
  154. options[5] = getId('_cbRestyleReports').checked;
  155. options[6] = getId('_cbDisableMapBlocker').checked;
  156. options[7] = getId('_cbNarrowSidePanel').checked;
  157.  
  158. localStorage.WMEFixUI = JSON.stringify(options);
  159. }
  160. };
  161. window.addEventListener("beforeunload", saveOptions, false);
  162.  
  163. // apply the settings
  164. setTimeout(applyAllSettings, 2000);
  165. wmefuinit = true;
  166. window.console.log("WMEFU: Initialised");
  167. }
  168.  
  169. function applyAllSettings() {
  170. moveZoomBar();
  171. shrinkBlackBar();
  172. hideUserInfo();
  173. compressSegmentTab();
  174. restyleReports();
  175. disableMapBlocker();
  176. narrowSidePanel();
  177. applyCount += 1;
  178. }
  179.  
  180. function moveZoomBar() {
  181. var reportPanel = getId('panel-container');
  182. reportPanel.style.position = "absolute";
  183. if (_cbMoveZoomBar.checked) {
  184. addGlobalStyle('.olControlPanZoomBar { left: 10px; width: 30px; right: inherit; }');
  185. addGlobalStyle('#WMETB_ZoomLevelIndicator { left: 43px !important; right: inherit !important; }');
  186. if (document.body.dir != "rtl") {
  187. addGlobalStyle('.panel { left: 61px; }');
  188. } else {
  189. addGlobalStyle('.panel { right: inherit; }');
  190. }
  191. } else {
  192. addGlobalStyle('.olControlPanZoomBar { left: inherit; width: 30px; right: 10px; }');
  193. addGlobalStyle('#WMETB_ZoomLevelIndicator { left: inherit !important; right: 43px !important; }');
  194. if (document.body.dir != "rtl") {
  195. addGlobalStyle('.panel { left: inherit; }');
  196. } else {
  197. addGlobalStyle('.panel { right: 61px; }');
  198. }
  199. }
  200. }
  201.  
  202. function hideUserInfo() {
  203. // WME Panel Swap buttons - move them up if user info is hidden
  204. var PSButton1 = getId('WMEPS_UIButton');
  205. var PSButton2 = getId('WMEPS_EditButton');
  206. if (_cbHideUserInfo.checked) {
  207. addGlobalStyle('#sidebar #user-info #user-box { padding: 0px; }');
  208. addGlobalStyle('#sidebar #user-details .user-profile { display: none !important; }');
  209. if (PSButton1) PSButton1.style.top = '-27px';
  210. if (PSButton2) PSButton2.style.top = '-27px';
  211. // Keep My Layers toggle - move up if user info is hidden
  212. addGlobalStyle('.kml-toggle-container { top: -25px; }');
  213. } else {
  214. addGlobalStyle('#sidebar #user-info #user-box { padding: 20px; }');
  215. addGlobalStyle('#sidebar #user-details .user-profile { display: inherit !important; }');
  216. if (PSButton1) PSButton1.style.top = '0px';
  217. if (PSButton2) PSButton2.style.top = '0px';
  218. // Keep My Layers toggle - move back down if user info is shown
  219. addGlobalStyle('.kml-toggle-container { top: 13px; }');
  220. }
  221. }
  222.  
  223. function shrinkBlackBar() {
  224. var wm = getId('WazeMap');
  225. if (_cbShrinkBlackBar.checked) {
  226. addGlobalStyle('.topbar { height: 20px; line-height: 20px; }');
  227. addGlobalStyle('.topbar .location-info { font-size: 12px; }');
  228. } else {
  229. addGlobalStyle('.topbar { height: 30px; line-height: 30px; }');
  230. addGlobalStyle('.topbar .location-info { font-size: 15px; }');
  231. }
  232. // $(window).trigger('resize');
  233. window.dispatchEvent(new Event('resize'));
  234. }
  235.  
  236. function FALSEcompressSegmentTab() {
  237. _cbCompressSegmentTab.checked = _cbextraCBSection.checked;
  238. compressSegmentTab();
  239. }
  240.  
  241. function compressSegmentTab() {
  242. var ep=getId('edit-panel');
  243. if (_cbCompressSegmentTab.checked) {
  244. // shrink address
  245. addGlobalStyle('#edit-panel .primary-street { font-size: 14px; line-height: 15px; font-weight: 600; color: black; }');
  246. addGlobalStyle('#edit-panel .address-edit-view .preview .address-edit-btn:not(.disabled) { background-color: #FFF9C4; }');
  247. addGlobalStyle('#edit-panel .segment .address-edit-view, .edit-panel .segment .address-edit-view { margin-bottom: 5px; }');
  248. //shrink tabs
  249. addGlobalStyle('#sidebar .nav-tabs li a { padding: 4px; }');
  250. addGlobalStyle('#sidebar .nav-tabs { margin-bottom: 5px; }');
  251. //reduce some vertical margins
  252. addGlobalStyle('#edit-panel .contents { padding-top: 0px; }');
  253. addGlobalStyle('#edit-panel .form-group { margin-bottom: 2px; line-height: 1; font-size: 11px; }');
  254. addGlobalStyle('#edit-panel .selection { margin-bottom: 5px; }');
  255. addGlobalStyle('#sidebar .side-panel-section:not(:last-child) { margin-bottom: 2px; }');
  256. addGlobalStyle('#sidebar .side-panel-section:not(:last-child)::after { margin-top: 5px; margin-bottom: 2px; }');
  257. addGlobalStyle('#edit-panel .control-label { margin-bottom: 1px; }');
  258. addGlobalStyle('#sidebar .controls-container { padding-top: 2px; }');
  259. addGlobalStyle('#edit-panel .segment .speed-limit label { margin-bottom: 0px; }');
  260. addGlobalStyle('#edit-panel .more-actions { padding-top: 2px; }');
  261. addGlobalStyle('#edit-panel .segment .speed-limit .direction-label, #edit-panel .segment .speed-limit .unit-label { line-height: 2.1em; }');
  262. //shrink dropdown controls & buttons
  263. addGlobalStyle('#edit-panel button, #edit-panel select, #edit-panel .form-control { font-size: 11px; height: 22px; padding: 0px 4px; }');
  264. addGlobalStyle('#edit-panel .more-actions button:not(:last-of-type) { margin-bottom: 2px; }');
  265. addGlobalStyle('.edit-closure .input-group-addon { padding: 2px 8px; }');
  266. //fit road property checkboxes on one line for all three (if text length allows)
  267. addGlobalStyle('#edit-panel .controls-container { display: inline-block; }');
  268. addGlobalStyle('#edit-panel .controls-container label { font-size: 12px; line-height: 18px; padding-left: 22px; }');
  269. addGlobalStyle('#edit-panel .select-entire-street { width: 49%; overflow: hidden; }');
  270. addGlobalStyle('#edit-panel .edit-house-numbers { width: 49%; overflow: hidden; }');
  271. addGlobalStyle('#edit-panel .action-button { color: black; }');
  272. } else {
  273. //enlarge address
  274. addGlobalStyle('#edit-panel .primary-street { font-size: 18px; line-height: 24px; font-weight: inherit; color: inherit; }');
  275. addGlobalStyle('#edit-panel .address-edit-view .preview .address-edit-btn:not(.disabled) { background-color: inherit; }');
  276. addGlobalStyle('#edit-panel .segment .address-edit-view, .edit-panel .segment .address-edit-view { margin-bottom: 20px; }');
  277. //enlarge tabs
  278. addGlobalStyle('#sidebar .nav-tabs li a { padding: 5px 15px; }');
  279. addGlobalStyle('#sidebar .nav-tabs { margin-bottom: 20px; }');
  280. //restore vertical margins
  281. addGlobalStyle('#edit-panel .contents { padding-top: 20px; }');
  282. addGlobalStyle('#edit-panel .form-group { margin-bottom: 10px; line-height: 1.43; font-size: 13px; }');
  283. addGlobalStyle('#edit-panel .selection { margin-bottom: 20px; }');
  284. addGlobalStyle('#sidebar .side-panel-section:not(:last-child) { margin-bottom: 21px; }');
  285. addGlobalStyle('#sidebar .side-panel-section:not(:last-child)::after { margin-top: 21px; margin-bottom: 21px; }');
  286. addGlobalStyle('#edit-panel .control-label { margin-bottom: 5px; }');
  287. addGlobalStyle('#sidebar .controls-container { padding-top: 7px; }');
  288. addGlobalStyle('#edit-panel .segment .speed-limit label { margin-bottom: 5px; }');
  289. addGlobalStyle('#edit-panel .more-actions { padding-top: 10px; }');
  290. addGlobalStyle('#edit-panel .segment .speed-limit .direction-label, #edit-panel .segment .speed-limit .unit-label { line-height: 2.5em; }');
  291. //enlarge dropdown controls & buttons
  292. addGlobalStyle('#edit-panel button, #edit-panel select, #edit-panel .form-control { font-size: 13px; height: 32px; padding: 6px 12px; }');
  293. addGlobalStyle('#edit-panel .more-actions button:not(:last-of-type) { margin-bottom: 10px; }');
  294. addGlobalStyle('.edit-closure .input-group-addon { padding: 6px 8px; }');
  295. //restore road property checkboxes to one line per item
  296. addGlobalStyle('#edit-panel .controls-container { display: inherit; }');
  297. addGlobalStyle('#edit-panel .controls-container label { font-size: inherit; line-height: inherit; padding-left: 25px; }');
  298. addGlobalStyle('#edit-panel .select-entire-street { width: 100%; overflow: inherit; }');
  299. addGlobalStyle('#edit-panel .edit-house-numbers { width: 100%; overflow: inherit; }');
  300. addGlobalStyle('#edit-panel .action-button { color: inherit; }');
  301. }
  302. //tweak required for Speedhelper script
  303. addGlobalStyle('div[id^="spd_"] { line-height: 1.43; }');
  304. }
  305.  
  306. function restyleReports() {
  307. if (_cbRestyleReports.checked) {
  308. addGlobalStyle('#panel-container .panel { font-size: 12px; line=height: 1; }');
  309. addGlobalStyle('#panel-container .problem-edit .header { padding: 5px 10px; line-height: 15px; }');
  310. addGlobalStyle('#panel-container .problem-edit .problem-data .title { line-height: 22px; }');
  311. addGlobalStyle('#panel-container .problem-edit .section .content { padding: 5px; }');
  312. addGlobalStyle('#WMEFP-UR-ALLPM { top: -2px !important; }');
  313. addGlobalStyle('#panel-container .problem-edit .conversation.section .comment .comment-content { padding: 5px; }');
  314. addGlobalStyle('#panel-container .problem-edit .conversation.section .new-comment-form { padding: 5px; }');
  315. addGlobalStyle('#panel-container .problem-edit .conversation.section .new-comment-form textarea { resize: vertical; height: 110px; margin-bottom: 5px; padding: 3px 5px; font-size: 12px; }');
  316. addGlobalStyle('#panel-container .btn { height: 20px; padding: 0px 10px;}');
  317. addGlobalStyle('#panel-container .problem-edit .actions .content { padding: 2px 5px;}');
  318. addGlobalStyle('#panel-container .problem-edit .actions .controls-container label { margin-bottom: 2px; }');
  319. addGlobalStyle('#panel-container .problem-edit .actions .navigation { margin-top: 5px;}');
  320. addGlobalStyle('#panel-container .problem-edit .actions .controls-container { display: inline-flex; flex-wrap: wrap; }');
  321. } else {
  322. addGlobalStyle('#panel-container .panel { font-size: inherit; line=height: inherit; }');
  323. addGlobalStyle('#panel-container .problem-edit .header { padding: 10px 15px; line-height: 21px; }');
  324. addGlobalStyle('#panel-container .problem-edit .problem-data .title { line-height: 40px; }');
  325. addGlobalStyle('#panel-container .problem-edit .section .content { padding: 15px; }');
  326. addGlobalStyle('#WMEFP-UR-ALLPM { top: 10px !important; }');
  327. addGlobalStyle('#panel-container .problem-edit .conversation.section .comment .comment-content { padding: 10px 15px 10px 15px; }');
  328. addGlobalStyle('#panel-container .problem-edit .conversation.section .new-comment-form { padding: 15px 15px 10px 15px; }');
  329. addGlobalStyle('#panel-container .problem-edit .conversation.section .new-comment-form textarea { resize: none; height: 70px; margin-bottom: 10px; padding: 6px 10px; font-size: 13px; }');
  330. addGlobalStyle('#panel-container .btn { height: inherit; padding: 6px 20px;}');
  331. addGlobalStyle('#panel-container .problem-edit .actions .content { padding: 15px;}');
  332. addGlobalStyle('#panel-container .problem-edit .actions .controls-container label { margin-bottom: 12px; }');
  333. addGlobalStyle('#panel-container .problem-edit .actions .navigation { margin-top: 10px;}');
  334. addGlobalStyle('#panel-container .problem-edit .actions .controls-container { display: inherit; flex-wrap: inherit; }');
  335. }
  336. }
  337.  
  338. function disableMapBlocker() {
  339. if (_cbDisableMapBlocker.checked) {
  340. addGlobalStyle('#popup-overlay { width: 0%; height: 0%; }');
  341. } else {
  342. addGlobalStyle('#popup-overlay { width: 100%; height: 100%; }');
  343. }
  344. }
  345.  
  346. function narrowSidePanel() {
  347. if (_cbNarrowSidePanel.checked) {
  348. addGlobalStyle('.row-fluid #sidebar { width: 250px; }');
  349. addGlobalStyle('.col-fixed-330 { width: 250px; }');
  350. if (document.body.dir != "rtl") {
  351. addGlobalStyle('.show-sidebar .row-fluid .fluid-fixed { margin-left: 250px; }');
  352. addGlobalStyle('.col-offset-330 { padding-left: 250px; }');
  353. } else {
  354. addGlobalStyle('.show-sidebar .row-fluid .fluid-fixed { margin-right: 250px; }');
  355. addGlobalStyle('.col-offset-330 { padding-right: 250px; }');
  356. }
  357. addGlobalStyle('.edit-closure .form { padding: 2px; }');
  358. addGlobalStyle('.edit-closure .date-input-group { width: 56%; }');
  359. } else {
  360. addGlobalStyle('.row-fluid #sidebar { width: 330px; }');
  361. addGlobalStyle('.col-fixed-330 { width: 330px; }');
  362. if (document.body.dir != "rtl") {
  363. addGlobalStyle('.show-sidebar .row-fluid .fluid-fixed { margin-left: 330px; }');
  364. addGlobalStyle('.col-offset-330 { padding-left: 330px; }');
  365. } else {
  366. addGlobalStyle('.show-sidebar .row-fluid .fluid-fixed { margin-right: 330px; }');
  367. addGlobalStyle('.col-offset-330 { padding-right: 330px; }');
  368. }
  369. addGlobalStyle('.edit-closure .form { padding 15px; }');
  370. addGlobalStyle('.edit-closure .date-input-group { width: 62%; }');
  371. }
  372. // $(window).trigger('resize')
  373. window.dispatchEvent(new Event('resize'));
  374. }
  375.  
  376. //Helper functions
  377.  
  378. function addGlobalStyle(css) {
  379. var head, style;
  380. head = document.getElementsByTagName('head')[0];
  381. if (!head) {
  382. return;
  383. }
  384. style = document.createElement('style');
  385. style.type = 'text/css';
  386. style.innerHTML = css;
  387. head.appendChild(style);
  388. }
  389.  
  390. function getElementsByClassName(classname, node) {
  391. if(!node) node = document.getElementsByTagName("body")[0];
  392. var a = [];
  393. var re = new RegExp('\\b' + classname + '\\b');
  394. var els = node.getElementsByTagName("*");
  395. for (var i=0,j=els.length; i<j; i++)
  396. if (re.test(els[i].className)) a.push(els[i]);
  397. return a;
  398. }
  399.  
  400. function getId(node) {
  401. return document.getElementById(node);
  402. }
  403.  
  404. // Start it running
  405. setTimeout(initialiseFixUI, 500);
  406. })();