Waze Edit Count Monitor

Displays your daily edit count in the WME toolbar. Warns if you might be throttled.

当前为 2018-04-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Waze Edit Count Monitor
  3. // @namespace https://greasyfork.org/en/users/45389-mapomatic
  4. // @version 2018.01.07.001
  5. // @description Displays your daily edit count in the WME toolbar. Warns if you might be throttled.
  6. // @author MapOMatic
  7. // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor\/?.*$/
  8. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
  9. // @license GNU GPLv3
  10. // @grant GM_xmlhttpRequest
  11. // @connect www.waze.com
  12.  
  13. // ==/UserScript==
  14.  
  15. /* global W */
  16. /* global GM_info */
  17.  
  18. // This function is injected into the page to allow it to run in the page's context.
  19. function WECM_Injected() {
  20. "use strict";
  21. var debugLevel = 0;
  22. var $outputElem = null;
  23. var $outputElemContainer = null;
  24. var lastEditCount = null;
  25. var userName = null;
  26. var savesWithoutIncrease = 0;
  27. var lastURCount = null;
  28. var tooltipText = 'Your daily edit count from your profile. Click to open your profile.';
  29.  
  30. function log(message, level) {
  31. if (message && level <= debugLevel) {
  32. console.log('Edit Count Monitor: ' + message);
  33. }
  34. }
  35.  
  36. function checkEditCount() {
  37. window.postMessage(JSON.stringify(['wecmGetCounts',userName]),'*');
  38. }
  39.  
  40. function updateEditCount(editCount, urCount, noIncrement) {
  41. var textColor;
  42. var bgColor;
  43. var tooltipTextColor;
  44.  
  45. // Add the counter div if it doesn't exist.
  46. if ($('#wecm-count').length === 0) {
  47. $outputElemContainer = $('<div>', {style:'position:relative; border-radius:23px; text-color:#354148; height:24px; padding-top:1px; padding-left:10px; padding-right:10px; display:block; float:right; margin-top:11px; font-weight:bold; font-size:medium;'}); //margin:9px 5px 8px 5px; display:inline;
  48. $outputElem = $('<a>', {id: 'wecm-count',
  49. href:'https://www.waze.com/user/editor/' + userName.toLowerCase(),
  50. target: "_blank",
  51. style:'text-decoration:none',
  52. 'data-original-title': tooltipText});
  53. $outputElemContainer.append($outputElem);
  54. $('#edit-buttons').children().first().append($outputElemContainer);
  55. $outputElem.tooltip({
  56. placement: 'auto top',
  57. delay: {show: 100, hide: 100},
  58. html: true,
  59. template: '<div class="tooltip" role="tooltip" style="opacity:0.95"><div class="tooltip-arrow"></div><div class="my-tooltip-header" style="display:block;"><b></b></div><div class="my-tooltip-body tooltip-inner" style="display:block; font-weight:600; !important"></div></div>'
  60. });
  61. }
  62.  
  63. log('edit count = ' + editCount + ', UR count = ' + urCount.count, 1);
  64. if (lastEditCount !== editCount || lastURCount.count !== urCount.count) {
  65. savesWithoutIncrease = 0;
  66. } else {
  67. if (!noIncrement) savesWithoutIncrease += 1;
  68. }
  69.  
  70. switch (savesWithoutIncrease) {
  71. case 0:
  72. case 1:
  73. textColor = '#354148';
  74. bgColor = '';
  75. tooltipTextColor = 'white';
  76. break;
  77. case 2:
  78. textColor = '#354148';
  79. bgColor = 'yellow';
  80. tooltipTextColor = 'black';
  81. break;
  82. default:
  83. textColor = 'white';
  84. bgColor = 'red';
  85. tooltipTextColor = 'white';
  86. }
  87. $outputElemContainer.css('background-color', bgColor);
  88. $outputElem.css('color', textColor).html(editCount);
  89. var urCountText = "<div style='margin-top:8px;padding:3px;'>UR's&nbsp;Closed:&nbsp;" + urCount.count + "&nbsp;&nbsp;(since&nbsp;" + (new Date(urCount.since)).toLocaleDateString() + ")</div>";
  90. var warningText = (savesWithoutIncrease > 0) ? "<div style='border-radius:8px;padding:3px;margin-top:8px;margin-bottom:5px;color:"+ tooltipTextColor + ";background-color:" + bgColor + ";'>" + savesWithoutIncrease + ' consecutive saves without an increase. (Are you throttled?)</div>' : '';
  91. $outputElem.attr('data-original-title', tooltipText + urCountText + warningText);
  92. lastEditCount = editCount;
  93. lastURCount = urCount;
  94. }
  95.  
  96. function receiveMessage(event) {
  97. var msg;
  98. try {
  99. msg = JSON.parse(event.data);
  100. } catch (err) {
  101. // Do nothing
  102. }
  103.  
  104. if (msg && msg[0] === "wecmUpdateUi") {
  105. var editCount = msg[1][0];
  106. var urCount = msg[1][1];
  107. updateEditCount(editCount, urCount);
  108. }
  109. }
  110.  
  111. function init() {
  112. userName = W.loginManager.user.userName;
  113. // Listen for events from sandboxed code.
  114. window.addEventListener('message', receiveMessage);
  115. // Listen for Save events.
  116. W.model.actionManager.events.register('afterclearactions', null, function(){ checkEditCount(); });
  117. // Update the edit count first time.
  118. checkEditCount();
  119. log('Initialized.',0);
  120. }
  121.  
  122. function bootstrap() {
  123. if (W &&
  124. W.loginManager &&
  125. W.loginManager.events &&
  126. W.loginManager.events.register &&
  127. W.map &&
  128. W.loginManager.isLoggedIn()) {
  129. log('Initializing...', 0);
  130. init();
  131. } else {
  132. log('Bootstrap failed. Trying again...', 0);
  133. window.setTimeout(function () {
  134. bootstrap();
  135. }, 1000);
  136. }
  137. }
  138.  
  139. bootstrap();
  140. }
  141.  
  142.  
  143. // Code that is NOT injected into the page.
  144. // Note that jQuery may or may not be available, so don't rely on it in this part of the script.
  145. (function(){
  146. 'use strict';
  147.  
  148. function getEditorProfileFromSource(source) {
  149. var match = source.match(/gon.data=({.*?});gon.env=/i);
  150. return JSON.parse(match[1]);
  151. }
  152.  
  153. function getEditCountFromProfile(profile) {
  154. var editingActivity = profile.editingActivity;
  155. return editingActivity[editingActivity.length-1];
  156. }
  157.  
  158. function getURCountFromProfile(profile) {
  159. var editsByType = profile.editsByType;
  160. for (var i=0; i < editsByType.length; i++) {
  161. if (editsByType[i].key === 'mapUpdateRequest') {
  162. return editsByType[i].value;
  163. }
  164. }
  165. return -1;
  166. }
  167.  
  168. // Handle messages from the page.
  169. function receiveMessage(event) {
  170. var msg;
  171. try {
  172. msg = JSON.parse(event.data);
  173. }
  174. catch (err) {
  175. // Ignore errors
  176. }
  177.  
  178. if (msg && msg[0] === "wecmGetCounts") {
  179. var userName = msg[1];
  180. GM_xmlhttpRequest({
  181. method: "GET",
  182. url: 'https://www.waze.com/user/editor/' + userName,
  183. onload: function(res) {
  184. var profile = getEditorProfileFromSource(res.responseText);
  185. window.postMessage(JSON.stringify(['wecmUpdateUi',[getEditCountFromProfile(profile), getURCountFromProfile(profile)]]),'*');
  186. }
  187. });
  188. }
  189. }
  190.  
  191. var WECM_Injected_script = document.createElement("script");
  192. WECM_Injected_script.textContent = "" + WECM_Injected.toString() + " \n" + "WECM_Injected();";
  193. WECM_Injected_script.setAttribute("type", "application/javascript");
  194. document.body.appendChild(WECM_Injected_script);
  195. window.addEventListener('message', receiveMessage);
  196.  
  197. // Listen for events coming from the page script.
  198. window.addEventListener('message', receiveMessage);
  199. })();