WME Form Filler

Use info from WME to automatically fill out related forms

当前为 2018-03-09 提交的版本,查看 最新版本

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