WME Form Filler

Use info from WME to automatically fill out related forms

当前为 2017-10-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WME Form Filler
  3. // @description Use info from WME to automatically fill out related forms
  4. // @namespace https://greasyfork.org/users/6605
  5. // @version 1.3.6.1
  6. // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor\/?.*$/
  7. // @author crazycaveman
  8. // @license MIT
  9. // @run-at document-end
  10. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NUIzRDdFNzAwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NUIzRDdFNzEwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1QjNEN0U2RTBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1QjNEN0U2RjBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtdrqLIAAAOCSURBVHjatJdLaBNBGMdn81ITQ2mLNqlIKInGkpSgFooPpKGHIlZPJqgoIvQivooPfFUsxYNVW62KiuItPah48RaUSlFEaDzEqgeV+sBUxag1rZa8Nv6nfMKaZpNssx34kdnN7sx/5nvNCtFolAUCAW8ymdwtCIKZMZZh6jQBjIIL4EkikWA+n485HI7/HtLFYjHH0NDQnXQ6XQkBbAbaGrAsHo+PNDc3T/lTF4lEVouiWKnX62O4DgBRpYn1YBuoAkuxwBGNRjNVAP7QZjKTu/4V7FJ59euAEWjlHtBg2//ZXEOq1WpzaUyWz690Ms5jUDhZcrqm0+UYyAPuKxyH2zqohgC++j/gmcJxRot5yGAwFBTAr9+AtWrHIqKMBYNBFgqFmlKpVLympuax1+udIiBD9reUON/nLMcTtFotC4fDBoR8H5JSVV1dXVdjY+OxbAEpUA8GSxRQC95KrkUe6jABzwnbkQ/OmUwmPSJQzBbAw+YL6C5hcr7y72TO2TTeI9AA7oErELNBp9NF5HzgEziogtnNZM6j4BfoAfNBB0XZu1wCuAkWggMKJ7sBXmbd4xmwH1wHW8FKut/Hi5NcFIiUu/cpFNCfQ0ACHKGdOM0LHbx/DE54HJWX92XDMEy7oKRFc9z7SXSBBZiYWSyWs0aj8QMvzVarVTYRJckP1GhLwN7J7Ugkhv1+f4/H48mbiPi+LOKeWmIUtIKP4AxFAiNn/F0oE/KX5wB3iQLSoAmsp3sPwW0q+3kF8HL8HFgVTqrJqvn8upf6XMyhYotRhsKnVqEAXj9ikuv9wEX9m/mKWy4fWA6eKhSwEdylfjVop/4PcEJJOebbOAz2KDgdC1kr7ATl1O+gUFwMXhcjgNvuG7g8TQdcAXZQ/xW4RLvxXk6ARmagBhqoTHJvFdhCUSLX2iVjttH7h8GEEh9wggEwiw4mfirRA2Sia2CnzHjV9HuLCs5FOpwmlERBGU3Om41+50nCzJ4nFCM0eTftlI/XAJ778WHCeDou5kg2SNtXLzkXPAAnKbWeymOCzWCM+nwRGT55S0sLs9lszG635xQgSCphivq9OU7LnQUcUJRMzts4T0JozOl0Ci6Xq6AJ+GHhPGUuNRo/jJRTGZbPAyiLIZzRJrBVZXi4bQY+TsfNZvMLWQEVFRVht9u9CQJaIcCk8uf5GArQVRxAh+Ue+ivAAAY7DIf3WTuXAAAAAElFTkSuQmCC
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. /*****************
  15. To-Do:
  16. *Allow manual user entries
  17. *Update closure date to number of days to close
  18. ******************/
  19.  
  20. (function()
  21. {
  22. var WMEFFName = GM_info.script.name;
  23. var WMEFFVersion = GM_info.script.version;
  24. var WMEFFIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NUIzRDdFNzAwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NUIzRDdFNzEwRTlGMTFFNkIyRDZGMzNERUFDMUM1NDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1QjNEN0U2RTBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo1QjNEN0U2RjBFOUYxMUU2QjJENkYzM0RFQUMxQzU0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtdrqLIAAAOCSURBVHjatJdLaBNBGMdn81ITQ2mLNqlIKInGkpSgFooPpKGHIlZPJqgoIvQivooPfFUsxYNVW62KiuItPah48RaUSlFEaDzEqgeV+sBUxag1rZa8Nv6nfMKaZpNssx34kdnN7sx/5nvNCtFolAUCAW8ymdwtCIKZMZZh6jQBjIIL4EkikWA+n485HI7/HtLFYjHH0NDQnXQ6XQkBbAbaGrAsHo+PNDc3T/lTF4lEVouiWKnX62O4DgBRpYn1YBuoAkuxwBGNRjNVAP7QZjKTu/4V7FJ59euAEWjlHtBg2//ZXEOq1WpzaUyWz690Ms5jUDhZcrqm0+UYyAPuKxyH2zqohgC++j/gmcJxRot5yGAwFBTAr9+AtWrHIqKMBYNBFgqFmlKpVLympuax1+udIiBD9reUON/nLMcTtFotC4fDBoR8H5JSVV1dXVdjY+OxbAEpUA8GSxRQC95KrkUe6jABzwnbkQ/OmUwmPSJQzBbAw+YL6C5hcr7y72TO2TTeI9AA7oErELNBp9NF5HzgEziogtnNZM6j4BfoAfNBB0XZu1wCuAkWggMKJ7sBXmbd4xmwH1wHW8FKut/Hi5NcFIiUu/cpFNCfQ0ACHKGdOM0LHbx/DE54HJWX92XDMEy7oKRFc9z7SXSBBZiYWSyWs0aj8QMvzVarVTYRJckP1GhLwN7J7Ugkhv1+f4/H48mbiPi+LOKeWmIUtIKP4AxFAiNn/F0oE/KX5wB3iQLSoAmsp3sPwW0q+3kF8HL8HFgVTqrJqvn8upf6XMyhYotRhsKnVqEAXj9ikuv9wEX9m/mKWy4fWA6eKhSwEdylfjVop/4PcEJJOebbOAz2KDgdC1kr7ATl1O+gUFwMXhcjgNvuG7g8TQdcAXZQ/xW4RLvxXk6ARmagBhqoTHJvFdhCUSLX2iVjttH7h8GEEh9wggEwiw4mfirRA2Sia2CnzHjV9HuLCs5FOpwmlERBGU3Om41+50nCzJ4nFCM0eTftlI/XAJ778WHCeDou5kg2SNtXLzkXPAAnKbWeymOCzWCM+nwRGT55S0sLs9lszG635xQgSCphivq9OU7LnQUcUJRMzts4T0JozOl0Ci6Xq6AJ+GHhPGUuNRo/jJRTGZbPAyiLIZzRJrBVZXi4bQY+TsfNZvMLWQEVFRVht9u9CQJaIcCk8uf5GArQVRxAh+Ue+ivAAAY7DIf3WTuXAAAAAElFTkSuQmCC';
  25. var forms = {};
  26.  
  27. function formfiller_bootstrap()
  28. {
  29. formfiller_log("Running bootstrap");
  30. /*var bGreasemonkeyServiceDefined = false;
  31. try
  32. {
  33. if ("object" === typeof Components.interfaces.gmIGreasemonkeyService)
  34. {
  35. bGreasemonkeyServiceDefined = true;
  36. }
  37. }
  38. catch (err)
  39. {
  40. //Ignore
  41. }
  42. if ("undefined" === typeof unsafeWindow || ! bGreasemonkeyServiceDefined)
  43. {
  44. unsafeWindow = ( function ()
  45. {
  46. var dummyElem = document.createElement('p');
  47. dummyElem.setAttribute('onClick','return window;');
  48. return dummyElem.onclick ();
  49. } )();
  50. }*/
  51.  
  52. if (typeof Waze.app === 'undefined' || !window.Waze.map)
  53. {
  54. setTimeout(formfiller_bootstrap,500);
  55. return;
  56. }
  57. formfiller_log("Starting init");
  58. formfiller_init();
  59. }
  60.  
  61. function formfiller_init()
  62. {
  63. // Check document elements are ready
  64. var userInfo = document.getElementById("user-info");
  65. if (userInfo === null)
  66. {
  67. window.setTimeout(formfiller_init,500);
  68. return;
  69. }
  70. var userTabs = document.getElementById("user-tabs");
  71. if (userTabs === null)
  72. {
  73. window.setTimeout(formfiller_init,500);
  74. return;
  75. }
  76. var navTab = userInfo.getElementsByTagName("ul");
  77. if (navTab.length === 0)
  78. {
  79. window.setTimeout(formfiller_init,500);
  80. return;
  81. }
  82. if (typeof navTab[0] === "undefined")
  83. {
  84. window.setTimeout(formfiller_init,500);
  85. return;
  86. }
  87. var tabContent = userInfo.getElementsByTagName("div");
  88. if (tabContent.length === 0)
  89. {
  90. window.setTimeout(formfiller_init,500);
  91. return;
  92. }
  93. if (typeof tabContent[0] === "undefined")
  94. {
  95. window.setTimeout(formfiller_init,500);
  96. return;
  97. }
  98.  
  99. ff_addUserTab();
  100. ff_addFormBtn();
  101. var formFillerObserver = new MutationObserver(function(mutations) {
  102. mutations.forEach(function(mutation) {
  103. // Mutation is a NodeList and doesn't support forEach like an array
  104. for (var i = 0; i < mutation.addedNodes.length; i++) {
  105. var addedNode = mutation.addedNodes[i];
  106.  
  107. // Only fire up if it's a node
  108. if (addedNode.nodeType === Node.ELEMENT_NODE) {
  109. var selectionDiv = addedNode.querySelector('div.selection');
  110.  
  111. if (selectionDiv) {
  112. ff_addFormBtn();
  113. }
  114. }
  115. }
  116. });
  117. });
  118. formFillerObserver.observe(document.getElementById("edit-panel"), { childList: true, subtree: true });
  119. //Waze.selectionManager.events.register("selectionchanged", null, ff_addFormBtn);
  120. if (Waze.app.modeController) {
  121. Waze.app.modeController.model.bind('change:mode', function(model, modeId) {
  122. if (modeId == 0) {
  123. ff_addUserTab();
  124. }
  125. });
  126. }
  127. formfiller_log("Init done");
  128. return;
  129. }
  130.  
  131. //Shamelessly copied from https://gist.github.com/CalebGrove/c285a9510948b633aa47
  132. function abbrState(input, to)
  133. {
  134. var states = [
  135. ['Arizona', 'AZ'],
  136. ['Alabama', 'AL'],
  137. ['Alaska', 'AK'],
  138. ['Arizona', 'AZ'],
  139. ['Arkansas', 'AR'],
  140. ['California', 'CA'],
  141. ['Colorado', 'CO'],
  142. ['Connecticut', 'CT'],
  143. ['Delaware', 'DE'],
  144. ['Florida', 'FL'],
  145. ['Georgia', 'GA'],
  146. ['Hawaii', 'HI'],
  147. ['Idaho', 'ID'],
  148. ['Illinois', 'IL'],
  149. ['Indiana', 'IN'],
  150. ['Iowa', 'IA'],
  151. ['Kansas', 'KS'],
  152. ['Kentucky', 'KY'],
  153. ['Kentucky', 'KY'],
  154. ['Louisiana', 'LA'],
  155. ['Maine', 'ME'],
  156. ['Maryland', 'MD'],
  157. ['Massachusetts', 'MA'],
  158. ['Michigan', 'MI'],
  159. ['Minnesota', 'MN'],
  160. ['Mississippi', 'MS'],
  161. ['Missouri', 'MO'],
  162. ['Montana', 'MT'],
  163. ['Nebraska', 'NE'],
  164. ['Nevada', 'NV'],
  165. ['New Hampshire', 'NH'],
  166. ['New Jersey', 'NJ'],
  167. ['New Mexico', 'NM'],
  168. ['New York', 'NY'],
  169. ['North Carolina', 'NC'],
  170. ['North Dakota', 'ND'],
  171. ['Ohio', 'OH'],
  172. ['Oklahoma', 'OK'],
  173. ['Oregon', 'OR'],
  174. ['Pennsylvania', 'PA'],
  175. ['Rhode Island', 'RI'],
  176. ['South Carolina', 'SC'],
  177. ['South Dakota', 'SD'],
  178. ['Tennessee', 'TN'],
  179. ['Texas', 'TX'],
  180. ['Utah', 'UT'],
  181. ['Vermont', 'VT'],
  182. ['Virginia', 'VA'],
  183. ['Washington', 'WA'],
  184. ['West Virginia', 'WV'],
  185. ['Wisconsin', 'WI'],
  186. ['Wyoming', 'WY'],
  187. ['Puerto Rico', 'PR'],
  188. ['Virgin Islands (U.S.)', 'VI']
  189. ];
  190.  
  191. if (to == 'abbr'){
  192. input = input.replace(/\w+/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
  193. for(i = 0; i < states.length; i++){
  194. if(states[i][0] == input){
  195. return(states[i][1]);
  196. }
  197. }
  198. } else if (to == 'name'){
  199. input = input.toUpperCase();
  200. for(i = 0; i < states.length; i++){
  201. if(states[i][1] == input){
  202. return(states[i][0]);
  203. }
  204. }
  205. }
  206. }
  207.  
  208. function formfiller_log(message)
  209. {
  210. if (typeof message === 'string')
  211. console.log('FormFiller: ' + message);
  212. else
  213. console.log('FormFiller: ', message);
  214. }
  215.  
  216. function ff_getStreetName(sel)
  217. {
  218. var streetName = "";
  219.  
  220. for (i=0; i<sel.length; i++)
  221. {
  222. var newStreet = Waze.model.streets.get(sel[i].model.attributes.primaryStreetID);
  223. if (typeof newStreet === "undefined" || newStreet.name === null)
  224. newStreet = "No Name";
  225. if (streetName === "")
  226. streetName = newStreet.name;
  227. else if (streetName != newStreet.name)
  228. streetName += ", "+newStreet.name;
  229. }
  230. return streetName;
  231. }
  232.  
  233. function ff_getState(sel)
  234. {
  235. var stateName = "";
  236.  
  237. for (i=0; i<sel.length; i++)
  238. {
  239. var cID = Waze.model.streets.get(sel[i].model.attributes.primaryStreetID).cityID;
  240. var sID = Waze.model.cities.get(cID).attributes.stateID;
  241. var newState = Waze.model.states.get(sID).name;
  242. if (newState === "")
  243. {
  244. sID = Waze.model.cities.get(cID).attributes.countryID;
  245. newState = Waze.model.countries.get(sID).name;
  246. formfiller_log('cID: '+cID);
  247. formfiller_log('sID: '+sID);
  248. formfiller_log('newState: '+newState);
  249. }
  250. if (stateName === "")
  251. stateName = newState;
  252. else if (stateName != newState)
  253. {
  254. stateName = "";
  255. break;
  256. }
  257. }
  258. return stateName;
  259. }
  260.  
  261. function ff_getCity(sel)
  262. {
  263. var cityName = "";
  264. for (i=0; i<sel.length; i++)
  265. {
  266. var cID = Waze.model.streets.get(sel[i].model.attributes.primaryStreetID).cityID;
  267. var newCity = Waze.model.cities.get(cID).attributes.name;
  268. if (cityName === "")
  269. cityName = newCity;
  270. else if (cityName != newCity)
  271. {
  272. cityName = "";
  273. break;
  274. }
  275. }
  276. return cityName;
  277. }
  278.  
  279. function ff_getCounty(sel)
  280. {
  281. var county = "";
  282. var center = Waze.map.center.clone().transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  283. //formfiller_log("Getting county for "+center.lat.toString()+","+center.lon.toString());
  284. var xhr = new XMLHttpRequest();
  285. xhr.open("GET",'https://maps.googleapis.com/maps/api/geocode/json?latlng='+center.lat+','+center.lon,false);
  286. xhr.onload = function () {
  287. if (xhr.readyState === 4) {
  288. if (xhr.status === 200) {
  289. var response = JSON.parse(xhr.responseText);
  290. var addrComps = response.results[0].address_components;
  291. for (comp = 0; comp < addrComps.length; comp++)
  292. {
  293. if (addrComps[comp].types.indexOf("administrative_area_level_2") !== -1)
  294. {
  295. county = addrComps[comp].long_name;
  296. //formfiller_log("ff_getCounty: "+county);
  297. var countyIndex = (county.indexOf(" County") !== -1 ? county.indexOf(" County") : county.indexOf(" Parish"));
  298. if (countyIndex !== -1)
  299. county = county.slice(0,countyIndex);
  300. break;
  301. }
  302. }
  303. }
  304. }
  305. };
  306. xhr.send(null);
  307. return county;
  308.  
  309. //Async call. Figure this out!
  310. /*return $.getJSON('https://maps.googleapis.com/maps/api/geocode/json?latlng='+center.lat+','+center.lon, function(data) {
  311. if (data.status === "OK")
  312. {
  313. var addrComps = data.results[0].address_components;
  314. for (comp = 0; comp < addrComps.length; comp++)
  315. {
  316. if (addrComps[comp].types.indexOf("administrative_area_level_2") !== -1)
  317. {
  318. county = addrComps[comp].long_name;
  319. county = county.slice(0,county.indexOf(" County"));
  320. formfiller_log("JSON func "+county);
  321. break;
  322. }
  323. }
  324. }
  325. if (county === "")
  326. county = "Not found";
  327. formfiller_log("Got county");
  328. formfiller_log(county);
  329. return county;
  330. });*/
  331. }
  332.  
  333. function ff_closureActive(sel)
  334. {
  335. for (i=0; i<sel.length; i++)
  336. {
  337. if (sel[i].model.hasClosures())
  338. if (Waze.model.roadClosures.getByAttributes({segID: sel[i].model.attributes.id})[0].active)
  339. return true;
  340. }
  341. return false;
  342. }
  343.  
  344. function ff_getClosureInfo(seg)
  345. {
  346. var closureInfo = {
  347. direction: "",
  348. endDate: "",
  349. idFwd: "",
  350. idRev: "",
  351. reason: ""
  352. };
  353. var segID = seg.model.attributes.id;
  354. var closureList = Waze.model.roadClosures.getByAttributes({segID: segID,active: true});
  355. /*if (closureList.length > 2)
  356. return closureList;
  357. if (closureList.length == 2 && closureList[0].forward != closureList[1].forward)
  358. closureInfo.direction = "Two-Way";
  359. else
  360. closureInfo.direction = "One-Way";*/
  361.  
  362. for (i=0; i<closureList.length; i++)
  363. {
  364. if (closureList[i].active === true)
  365. {
  366. if (closureInfo.endDate === "")
  367. {
  368. closureInfo.endDate = closureList[i].endDate;
  369. }
  370. else if (closureInfo.endDate > closureList[i].endDate)
  371. {
  372. closureInfo.endDate = closureList[i].endDate;
  373. }
  374. if (closureList[i].forward === true)
  375. {
  376. closureInfo.idFwd = closureList[i].id;
  377. }
  378. else
  379. {
  380. closureInfo.idRev = closureList[i].id;
  381. }
  382. if (closureInfo.reason === "")
  383. {
  384. closureInfo.reason = closureList[i].reason;
  385. }
  386. }
  387. }
  388.  
  389. if (closureInfo.idFwd !== "" && closureInfo.idRev !== "")
  390. closureInfo.direction = "Two-Way";
  391. else
  392. closureInfo.direction = "One-Way";
  393.  
  394. return closureInfo;
  395. }
  396.  
  397. function ff_createPermalink(selection)
  398. {
  399. //https://www.waze.com/editor/?env=usa&lon=-79.79248&lat=32.86150&layers=12709&zoom=5&mode=0&mapProblemFilter=1&mapUpdateRequestFilter=0&venueFilter=0&segments=504534141
  400. //https://www.waze.com/editor/?env=usa&lon=-79.79248&lat=32.86150&layers=12709&zoom=5&mode=0&mapProblemFilter=1&mapUpdateRequestFilter=0&venueFilter=0&venues=183632201.1836387542.3102948
  401. var permalink = "https://www.waze.com/editor/?", segIDs = [];
  402. var latLon = Waze.map.center.clone().transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  403. var lat = latLon.lat, lon = latLon.lon;
  404. var env = Waze.location.code;
  405. var type = "segments";
  406. var zoom = Waze.map.zoom;
  407.  
  408. /*if (zoom == 3)
  409. alert('Current zoom level (3) will not select street segments! If your selection includes street segments, please increase the zoom level');
  410. else if (zoom == 2)
  411. alert ('Current zoom level (2) will only select PS+ segments! If you have any other segment type selected, please increase the zoom level');
  412. else if (zoom <= 1)
  413. {
  414. alert ('Current zoom level ('+ zoom.toString() +') will not select any segments! Increase the zoom level before submitting!');
  415. return;
  416. }*/
  417.  
  418. //To get lat and long centered on segment
  419. if (selection.length == 1)
  420. {
  421. latLon = selection[0].model.getCenter().clone();
  422. latLon.transform(Waze.map.projection.projCode,Waze.map.displayProjection.projCode);
  423. lat = latLon.y;
  424. lon = latLon.x;
  425. }
  426.  
  427. var maxzoom = 2,
  428. zoomToRoadType = Waze.Config.segments.zoomToRoadType;
  429. for (i=0; i<selection.length; i++)
  430. {
  431. var segment = selection[i].model;
  432. if (segment.type != "segment")
  433. continue;
  434. segIDs.push(segment.attributes.id);
  435. if (zoomToRoadType[zoom] !== -1 && zoomToRoadType[zoom].indexOf(segment.attributes.roadType) === -1)
  436. {
  437. alert("This zoom level ("+ zoom.toString() +") cannot be used for this road type! Please increase your zoom:\n"+
  438. "Streets: 4+\nOther drivable and Non-drivable: 3+\nHighways and PS: 2+");
  439. formfiller_log("Zoom level not correct for segment: "+ zoom.toString() +" "+ segment.attributes.roadType.toString());
  440. return;
  441. }
  442. }
  443. permalink += "env="+env+"&lon="+lon+"&lat="+lat+"&zoom="+zoom.toString()+"&"+type+"="+segIDs.join();
  444. return permalink;
  445. }
  446.  
  447. function ff_createFormLink(formIndx)
  448. {
  449. var selection = Waze.selectionManager.selectedItems;
  450. var formInfo = {};
  451. var formDt = forms[formIndx];
  452. var formLink = formDt.url;
  453. if (selection.length === 0 || selection[0].model.type != "segment")
  454. {
  455. formfiller_log("No segments selected.");
  456. return;
  457. }
  458.  
  459. formInfo.username = encodeURIComponent(Waze.loginManager.user.userName);
  460. formInfo.streetname = encodeURIComponent(ff_getStreetName(selection));
  461. formInfo.permalink = encodeURIComponent(ff_createPermalink(selection));
  462. if (formInfo.permalink === "undefined")
  463. {
  464. formfiller_log("No permalink generated");
  465. return;
  466. }
  467. formInfo.county = ff_getCounty(selection);
  468.  
  469. formInfo.status = "REPORTED";
  470. formInfo.direction = "Two-Way";
  471. formInfo.reason = document.getElementById("ff-closure-reason").value;
  472. formInfo.endDate = document.getElementById("ff-closure-endDate").value +"+"+ document.getElementById("ff-closure-endTime").value;
  473. if (ff_closureActive(selection))
  474. {
  475. formInfo.status = "CLOSED";
  476. var closureInfo = ff_getClosureInfo(selection[0]);
  477. formInfo.direction = closureInfo.direction;
  478. formInfo.reason = encodeURIComponent(closureInfo.reason);
  479. formInfo.endDate = encodeURIComponent(closureInfo.endDate);
  480. }
  481. formInfo.notes = "Form+filled+by+"+WMEFFName+"+v"+WMEFFVersion;
  482.  
  483. //Need to do this part better, works for now
  484. formLink += "?entry."+formDt.username+"="+formInfo.username;
  485. formLink += "&entry."+formDt.streetname+"="+formInfo.streetname;
  486. formLink += "&entry."+formDt.permalink+"="+formInfo.permalink;
  487. if (formDt.hasOwnProperty('state'))
  488. {
  489. formInfo.state = abbrState(ff_getState(selection),"abbr"); //Abbreviation
  490. formLink += "&entry."+formDt.state+"="+formInfo.state;
  491. }
  492. if (formDt.hasOwnProperty('city'))
  493. {
  494. formInfo.city = encodeURIComponent(ff_getCity(selection));
  495. formLink += "&entry."+formDt.city+"="+formInfo.city;
  496. }
  497. formLink += "&entry."+formDt.county+"="+formInfo.county;
  498. formLink += "&entry."+formDt.status+"="+formInfo.status;
  499. formLink += "&entry."+formDt.direction+"="+formInfo.direction;
  500. formLink += "&entry."+formDt.reason+"="+formInfo.reason;
  501. formLink += "&entry."+formDt.endDate+"="+formInfo.endDate;
  502. formLink += "&entry."+formDt.notes+"="+formInfo.notes;
  503. formfiller_log(formLink);
  504. return formLink;
  505. }
  506.  
  507. function ff_addFormBtn()
  508. {
  509. var selection = Waze.selectionManager.selectedItems;
  510. if (selection.length === 0 || selection[0].model.type != "segment")
  511. {
  512. //formfiller_log("No segments selected.");
  513. return;
  514. }
  515. if (document.getElementById("formfillerDiv"))
  516. {
  517. //formfiller_log("Div already created");
  518. return;
  519. }
  520.  
  521. forms = [
  522. {
  523. //https://docs.google.com/forms/d/1QUIfaR2FKRLU8TTlJq1KVJ595nkeDGS9_riSuBVMDDI/viewform?entry.1553765347=username&entry.1264424583=CLOSED&entry.1811077109=permalink&entry.792657790=Two-Way&entry.345142186=reason&entry.1102521735=2016-09-20+03:00&entry.2015424420=street+name&entry.1547375393=from+street&entry.1335391716=to+street&entry.1867193205=SC&entry.1714138473=county&entry.1803937317=source&entry.1648634142=notes
  524. name: 'USA VEOC Nate Weather related closures',
  525. url: 'https://docs.google.com/forms/d/e/1FAIpQLSduBiLMhbg6nRpsEVCTcVbV4eWmHDXdIKGtuaOvzy6NZLbSgw/viewform',
  526. username: '1553765347',
  527. status: '1264424583',
  528. permalink: '1811077109',
  529. direction: '792657790',
  530. reason: '345142186',
  531. endDate: '1102521735',
  532. streetname: '2015424420',
  533. fromStreet: '1547375393',
  534. toStreet: '1335391716',
  535. state: '1867193205',
  536. county: '1714138473',
  537. source: '1803937317',
  538. notes: '1648634142',
  539. },
  540. {
  541. //https://docs.google.com/forms/d/e/1FAIpQLSff7nsBw8qxCojBdxrjTPl6tercqyyzGy92Vif_SBdHkYDchw/viewform?entry.1204781462=Reporter&entry.828228572=Reported&entry.1647952662=Street+name+&entry.1501712688=From+street+&entry.2094306654=To+street+&entry.1414240321=Two-Way&entry.900957975=10/27/2016+00:00&entry.1051351191=Adams&entry.1093044522=City+&entry.1540676081=IDOT&entry.430378754=Reason+&entry.1754051160=Permalink+&entry.172235277=Source+&entry.1722909714=Notes+
  542. name: 'Illinois event/weather closures',
  543. url: 'https://docs.google.com/forms/d/e/1FAIpQLSff7nsBw8qxCojBdxrjTPl6tercqyyzGy92Vif_SBdHkYDchw/viewform',
  544. username: '1204781462',
  545. status: '828228572',
  546. permalink: '1754051160',
  547. direction: '1414240321',
  548. reason: '430378754',
  549. endDate: '900957975',
  550. streetname: '1647952662',
  551. fromStreet: '1501712688',
  552. toStreet: '2094306654',
  553. //state: '0',
  554. county: '1051351191',
  555. city: '1093044522',
  556. source: '172235277',
  557. notes: '1722909714',
  558. },
  559. /*{
  560. //https://docs.google.com/forms/d/e/1FAIpQLSeRVbj9DNsbP4GOeYr_6_2KjgS2TGi3f_Z5d9FVX1MmqMrZDQ/viewform?entry.1553765347=username&entry.1264424583=REPORTED&entry.1811077109=permalink&entry.792657790=Two-Way&entry.345142186=reason&entry.1102521735=2016-09-12+19:15&entry.2015424420=streetname&entry.1547375393=closure_from&entry.1335391716=closure_to&entry.1867193205=SC&entry.1714138473=county&entry.1803937317=source&entry.1648634142=notes
  561. name: 'Testing form weather closures',
  562. url: 'https://docs.google.com/forms/d/e/1FAIpQLSeRVbj9DNsbP4GOeYr_6_2KjgS2TGi3f_Z5d9FVX1MmqMrZDQ/viewform',
  563. username: '1553765347',
  564. status: '1264424583',
  565. permalink: '1811077109',
  566. direction: '792657790',
  567. reason: '345142186',
  568. endDate: '1102521735',
  569. streetname: '2015424420',
  570. fromStreet: '1547375393',
  571. toStreet: '1335391716',
  572. state: '1867193205',
  573. county: '1714138473',
  574. source: '1803937317',
  575. notes: '1648634142',
  576. },*/
  577. /*{
  578. //https://docs.google.com/forms/d/e/1FAIpQLScY_5WKyYTqvH1fdiBThqLO4DRIzFzgdBtBexw5-iKL_LOzBw/viewform?entry.1553765347=username&entry.1264424583=CLOSED&entry.1811077109=permalink&entry.792657790=Two-Way&entry.345142186=reason&entry.1102521735=2016-09-20+03:00&entry.2015424420=street+name&entry.1547375393=from+street&entry.1335391716=to+street&entry.1867193205=SC&entry.1714138473=county&entry.1803937317=source&entry.1648634142=notes
  579. name: 'USA Weather related closures',
  580. url: 'https://docs.google.com/forms/d/e/1FAIpQLScY_5WKyYTqvH1fdiBThqLO4DRIzFzgdBtBexw5-iKL_LOzBw/viewform',
  581. username: '1553765347',
  582. status: '1264424583',
  583. permalink: '1811077109',
  584. direction: '792657790',
  585. reason: '345142186',
  586. endDate: '1102521735',
  587. streetname: '2015424420',
  588. fromStreet: '1547375393',
  589. toStreet: '1335391716',
  590. state: '1867193205',
  591. county: '1714138473',
  592. source: '1803937317',
  593. notes: '1648634142',
  594. }*/
  595. ];
  596.  
  597. var ffDiv = document.createElement("div"),
  598. ffMnu = document.createElement("select"),
  599. ffBtn = document.createElement("button");
  600. ffDiv.id = "formfillerDiv";
  601. var formWindowName = "WME Form Filler result",
  602. formWindowSpecs = "resizable=1,menubar=0,scrollbars=1,status=0,toolbar=0";
  603. var editPanel, selElem, formLink;
  604. editPanel = document.getElementById("edit-panel");
  605. selElem = editPanel.getElementsByClassName("selection");
  606.  
  607. for (i=0; i<forms.length; i++)
  608. {
  609. ffMnu.options.add(new Option(forms[i].name,i));
  610. }
  611. ffBtn.innerHTML = "Go to Form";
  612. ffBtn.onclick = function()
  613. {
  614. //alert(ffMnu.options[ffMnu.selectedIndex].value+": "+forms[ffMnu.options[ffMnu.selectedIndex].value].name);
  615. ff_saveSettings();
  616. formLink = ff_createFormLink(ffMnu.options[ffMnu.selectedIndex].value);
  617. if (typeof formLink === "undefined")
  618. return;
  619.  
  620. if ($("#ff-open-in-tab").prop("checked"))
  621. window.open(formLink,"_blank");
  622. else
  623. window.open(formLink,formWindowName,formWindowSpecs);
  624. };
  625. ffDiv.appendChild(ffMnu);
  626. ffDiv.appendChild(ffBtn);
  627. selElem[0].appendChild(ffDiv);
  628.  
  629. return;
  630. }
  631.  
  632. function ff_loadSettings()
  633. {
  634. var todayDate = new Date(),
  635. futureDate = new Date(),
  636. daysInFuture = 3;
  637. var today = todayDate.getFullYear() +"-"+ (todayDate.getMonth()+1<10 ? "0"+(todayDate.getMonth()+1) : todayDate.getMonth()+1) +"-"+ todayDate.getDate();
  638. futureDate.setDate(futureDate.getDate() + daysInFuture);
  639.  
  640. var ffOpenInTab = localStorage.getItem("ff-open-in-tab");
  641. if (ffOpenInTab === "1")
  642. $("#ff-open-in-tab").trigger("click");
  643. var ffClosureReason = localStorage.getItem("ff-closure-reason");
  644. if (ffClosureReason !== null)
  645. $("#ff-closure-reason").val(ffClosureReason);
  646. var ffClosureEndDate = localStorage.getItem("ff-closure-endDate");
  647. if (ffClosureEndDate !== null && ffClosureEndDate !== "" && ffClosureEndDate >= today)
  648. $("#ff-closure-endDate").val(ffClosureEndDate);
  649. else
  650. {
  651. var closureDate = futureDate.getFullYear() +"-"+ (futureDate.getMonth()+1<10 ? "0"+(futureDate.getMonth()+1) : futureDate.getMonth()+1) +"-"+ (futureDate.getDate() < 10 ? "0"+futureDate.getDate() : futureDate.getDate());
  652. $("#ff-closure-endDate").val(closureDate);
  653. }
  654. var ffClosureEndTime = localStorage.getItem("ff-closure-endTime");
  655. if (ffClosureEndTime !== null && ffClosureEndTime !== "")
  656. $("#ff-closure-endTime").val(ffClosureEndTime);
  657. //formfiller_log("Settings loaded");
  658. return;
  659. }
  660.  
  661. function ff_saveSettings()
  662. {
  663. /*formfiller_log("Saving settings:\n"+$("#ff-open-in-tab").prop("checked")+
  664. "\n"+$("#ff-closure-reason").val()+
  665. "\n"+$("#ff-closure-endDate").val()+
  666. "\n"+$("#ff-closure-endTime").val());*/
  667. if ($("#ff-open-in-tab").prop("checked"))
  668. localStorage.setItem("ff-open-in-tab", "1");
  669. else
  670. localStorage.setItem("ff-open-in-tab", "0");
  671. localStorage.setItem("ff-closure-reason", $("#ff-closure-reason").val());
  672. localStorage.setItem("ff-closure-endDate", $("#ff-closure-endDate").val());
  673. localStorage.setItem("ff-closure-endTime", $("#ff-closure-endTime").val());
  674. //formfiller_log("Settings saved");
  675. return;
  676. }
  677.  
  678. function ff_addUserTab()
  679. {
  680. var userInfo = document.getElementById("user-info"),
  681. userTabs = document.getElementById("user-tabs"),
  682. navTabs = userTabs.getElementsByClassName("nav-tabs"),
  683. tabContent = userInfo.getElementsByClassName("tab-content");
  684. var ffTab = document.createElement("li"),
  685. ffPanel = document.createElement("div"),
  686. ffReason = document.createElement("div"),
  687. ffEndDate = document.createElement("div"),
  688. ffNewTabBox = document.createElement("input"),
  689. ffNewTabLabel = document.createElement("label"),
  690. ffTabInfo = document.createElement("div");
  691.  
  692. ffTab.innerHTML = '<a title="Form Filler" href="#sidepanel-formfill" data-toggle="tab"><img class="fa" src="'+WMEFFIcon+'" width="15px" /></a>';
  693. ffPanel.id = "sidepanel-formfill";
  694. ffPanel.className = "tab-pane";
  695.  
  696. ffTabInfo.innerHTML = '<b>'+ WMEFFName +'</b> v'+ WMEFFVersion;
  697.  
  698. ffNewTabBox.id = "ff-open-in-tab";
  699. ffNewTabBox.type = "checkbox";
  700. ffNewTabBox.name = "ff_open_tab";
  701.  
  702. ffNewTabLabel.innerHTML = "Open form in new tab";
  703. ffNewTabLabel.for = "ff_open_tab";
  704.  
  705. ffReason.className = "form-group";
  706. ffReason.innerHTML = '<label class="control-label" for="ff_closure_reason">Closures reason:</label><div class="controls"><input id="ff-closure-reason" class="form-control" type="text" name="ff_closure_reason"></div>';
  707.  
  708. ffEndDate.className = "form-group";
  709. ffEndDate.innerHTML = '<label class="control-label" for="ff_closure_endDate">Closures end:</label><div class="controls"><div class="date date-input-group input-group pull-left" style="width: 62%"><input id="ff-closure-endDate" class="form-control end-date" type="text" name="ff_closure_endDate"><span class="input-group-addon"><i class="fa fa-calendar"></i></span></div><div class="bootstrap-timepicker input-group style="width: 38%""><input id="ff-closure-endTime" class="end-time form-control" type="text" name="ff_closure_endTime"><span class="input-group-addon"><i class="fa fa-clock-o"></i></span></div></div>';
  710.  
  711. ffPanel.appendChild(ffTabInfo);
  712. ffPanel.appendChild(ffNewTabBox);
  713. ffPanel.appendChild(ffNewTabLabel);
  714. ffPanel.appendChild(ffReason);
  715. ffPanel.appendChild(ffEndDate);
  716. navTabs[0].appendChild(ffTab);
  717. tabContent[0].appendChild(ffPanel);
  718.  
  719. if (typeof $.fn.datepicker !== "undefined") {
  720. $("#ff-closure-endDate").datepicker({format:"yyyy-mm-dd", todayHighlight:true, autoclose:true});
  721. } else {
  722. if (typeof $.fn.daterangepicker !== "undefined") {
  723. $("#ff-closure-endDate").daterangepicker({singleDatePicker:true, locale:{format:"YYYY-MM-DD"}});
  724. }
  725. }
  726.  
  727. if (typeof $.fn.timepicker !== "undefined") {
  728. $("#ff-closure-endTime").timepicker({template:false,defaultTime:"00:00",showMeridian:false});
  729. }
  730.  
  731. ff_loadSettings();
  732. $("#ff-closure-reason").change(function() {ff_saveSettings();});
  733. $("#ff-closure-endDate").change(function() {ff_saveSettings();});
  734. $("#ff-closure-endTime").change(function() {ff_saveSettings();});
  735. $("#ff-open-in-tab").click(function() {ff_saveSettings();});
  736. }
  737.  
  738. setTimeout(formfiller_bootstrap,2000);
  739. })();