WME Closure Details

Provide access to all closure details within the closures list

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

  1. // ==UserScript==
  2. // @name WME Closure Details
  3. // @namespace http://www.tomputtemans.com/
  4. // @description Provide access to all closure details within the closures list
  5. // @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
  6. // @icon data:image/png;base64,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
  7. // @version 0.6.1
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. function init(e) {
  12. if (e && e.user == null) {
  13. return;
  14. }
  15. if (document.getElementById('user-info') == null) {
  16. setTimeout(init, 500);
  17. return;
  18. }
  19. if (typeof Waze.loginManager === 'undefined' || Waze.app.modeController === 'undefined' || Waze.selectionManager === 'undefined') {
  20. setTimeout(init, 300);
  21. return;
  22. }
  23. if (!Waze.loginManager.hasUser()) {
  24. Waze.loginManager.events.register('login', null, init);
  25. Waze.loginManager.events.register('loginStatus', null, init);
  26. // Double check as event might have triggered already
  27. if (!Waze.loginManager.hasUser()) {
  28. return;
  29. }
  30. }
  31.  
  32. // Deal with events mode
  33. if (Waze.app.modeController) {
  34. Waze.app.modeController.model.bind('change:mode', function(model, modeId) {
  35. if (modeId == 0) {
  36. observeContentsPane();
  37. }
  38. });
  39. }
  40. observeContentsPane();
  41. }
  42. init();
  43.  
  44. function observeContentsPane() {
  45. var observer = new MutationObserver(function (mutations) {
  46. mutations.forEach(function (mutation) {
  47. var closureBlocks = mutation.target.querySelectorAll('.closure-item');
  48. var selectedIDs = Waze.selectionManager.selectedItems.filter(function(obj) {
  49. return obj.model.type == 'segment';
  50. }).map(function(obj) {
  51. return obj.model.attributes.id;
  52. });
  53. var selectedClosures = Waze.model.roadClosures.getObjectArray().filter(function(closure) {
  54. return selectedIDs.indexOf(closure.segID) != -1;
  55. });
  56. for (var i = 0; i < closureBlocks.length; i++) {
  57. var closureBlock = closureBlocks[i];
  58. var matchedClosure = selectedClosures.find(function(closure) {
  59. return getLocalizedTime(closure.startDate) == getTimeFromBlock(closureBlock.querySelector('.start-date'))
  60. && getLocalizedTime(closure.endDate) == getTimeFromBlock(closureBlock.querySelector('.end-date'));
  61. });
  62. if (matchedClosure) {
  63. var description = closureBlock.querySelector('.description');
  64. if (description.childNodes.length > 0) { // Already contains information or perhaps bug has been fixed
  65. continue;
  66. }
  67. var info = document.createElement('i');
  68. info.className = 'fa fa-fw fa-info-circle';
  69. info.style.cursor = 'pointer';
  70. info.dataset.toggle = 'tooltip';
  71. info.title = (matchedClosure.permanent ? 'Ignores traffic' : 'Listens to traffic') + '<br/>Created by: ' + getUsername(matchedClosure.createdBy) + '<br/>Created on: ' + I18n.l('time.formats.long', matchedClosure.createdOn);
  72. if (matchedClosure.updatedBy) {
  73. info.title += '<br/>Updated by: ' + getUsername(matchedClosure.updatedBy);
  74. }
  75. if (matchedClosure.updatedOn) {
  76. info.title += '<br/>Updated on: ' + I18n.l('time.formats.long', matchedClosure.updatedOn);
  77. }
  78. description.appendChild(info);
  79. $(info).tooltip({
  80. html: true
  81. });
  82. if (matchedClosure.reason != '') {
  83. description.appendChild(document.createTextNode(matchedClosure.reason));
  84. } else {
  85. var indent = document.createElement('i');
  86. indent.appendChild(document.createTextNode('No description set'));
  87. description.appendChild(indent);
  88. }
  89. }
  90. }
  91. });
  92. });
  93. observer.observe(document.querySelector('.contents'), {
  94. childList: true
  95. });
  96. }
  97.  
  98. function getTimeFromBlock(node) {
  99. return node.querySelector('.date').textContent + ' ' + node.querySelector('.time').textContent;
  100. }
  101.  
  102. function getLocalizedTime(date) {
  103. var splitDate = date.split(' ');
  104. return I18n.l('date.formats.default', splitDate[0]) + ' ' + splitDate[1];
  105. }
  106.  
  107. function getUsername(id) {
  108. var user = Waze.model.users.get(id);
  109. if (user) {
  110. return user.userName;
  111. } else {
  112. return id + '(user not loaded)';
  113. }
  114. }