WME Form Filler

Use info from WME to automatically fill out related forms

当前为 2017-08-16 提交的版本,查看 最新版本

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