WME E95

Setup road properties with templates

安装此脚本?
作者推荐脚本

您可能也喜欢WME E50 Fetch POI Data

安装此脚本
  1. // ==UserScript==
  2. // @name WME E95
  3. // @name:uk WME 🇺🇦 E95
  4. // @version 0.8.3
  5. // @description Setup road properties with templates
  6. // @description:uk Швидке налаштування атрибутів вулиці за шаблонами
  7. // @license MIT License
  8. // @author Anton Shevchuk
  9. // @namespace https://greasyfork.org/users/227648-anton-shevchuk
  10. // @supportURL https://github.com/AntonShevchuk/wme-e95/issues
  11. // @match https://*.waze.com/editor*
  12. // @match https://*.waze.com/*/editor*
  13. // @exclude https://*.waze.com/user/editor*
  14. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wgMCC8ZXsb24AAACJpJREFUeNrtmnlUVNcdxz9vZhhANkFlE1kEogIuNTYGlAjqqWIV0+gxBmNsI9ETkqZGmhhqDtGkEo02YI8xJxXNIlhPXXJckLbuSzWWY4QIKIKK7Amyb8Js/WOGGZ4OMGKgHpjvOXNm5r7ffff+fve3fO99D8wwwwwzzDDDDDPMMGOAY+0A0nWd4afAug4NH+ACfArMExDs+pPOGjQNwBFgNev5sd0QMjQ6iThSA50DoxJmJODn5Iel1LJfLXqrqtWuoLogKu5EXFRuXG4qH/OyXnfiSYs+FK0ZKFhxeIWGeNK0IfA+YUFuQaevxVwD4GLxRaIPR3O39i4CQn9xf7wdvdkRuYMQjxAAgrYHkVOeEy7wPvtL3y1d4G7nTnp+OnO+mQMS6Ce6d7QCqOHYsmNE+EVQ2lCKxyceByRuDm7TXWxcAHj10Ksg7YfKo9NJCssPLQfA1cYVVwfXcIlcJndsV7iisqLfV8DyynK9QSxllk4yk+P8fg9HlIAgx5BwO0INKHXfglYWCxPuqdZ9TBgbiZFQ0DuFgMwUHaws7KheV491D/QvvpuM5xevgVzcLpPICQ34LRvD3uEZZz9QKzl4cyfxR9aQ01jXeRiqYcrYGF7yGoNao+ly7Mu3DpCad7bLkJaZlj80NLaBtfzRDdCkvP/wBCw8ufrGVYIGO3VYLRkvjF7JC6OjOZS5juf3/9n47FSw9Ok4Vo706HZsB8UtrQG6cZI+hYXFEErfuStWXgQp8yd8xKYpC0Fl3AOe9fIwaazuPKRPDCDKMUp4JewL3E3wpHcj9hHqYOSCrS/jpT/f/GQ96qUpI3znQqTyQd2KNjeXGEax8iV5ygLR9cNZn5KY+S1jXGfz2ay1+ooFsGl+MlNSo0UJ1N7B0+RpyqWyXjIAzZwpuARWj1CDgamBi0TN2UUpzN8XCzKBM7cucLnuHlcWJeqvj3ebhlQiRak2xELAUD/RPd47OJcbbRZG81xR1bVuOY2sL+N/3LBA0f+k429riRcakMD3WUnsCV5F1AgvAAbZevMLSxkZLQYDDLf36RDkFWy+mob6MUKiT5OgxwMxfb36nniFpHCq4JRofSI8vQw1XwMBwwwe0NZ0zyQ60Dse8ChkRBwJhsGFzki7AaH+4ZBzU3sfDbjZGCrA7Zo8JJYOBA3xwVomp6G1hjs1t2lRqkym8z00wGBWTXsDiazrMwONRkVyxl9pUGmVKmsQO9xMnwmc+yHTMFk1jHEZJ5IJdJpgsIkaRg/z119zcppK3ZpybCysEBBQq5WoFbUs2zuNPXdye9EAwlASf73NJNEDmdtoUGlj+EpZJvCS/tofZx8k8cZIapq1/yeNiyY2YJKov5u1g8g5vByG6v8627qInU0iQ2I5lNRlOXjvDyUh64Iux/yfcoBS1Sry6Is5qSJuY23jQ/VaNakLPuPvS8+S8eIOI3TOzXAP+VN4m8hGNyw8T4iz/ZOVBFGWsvzcPx6qkVETY1g8+rnO4ki/+k7Dpz/ShDdMizPOJh8/B7RypfQHBEnX/qVSK2jrSEelAnvOryR2YgRjbe2Mpj+lshELmW0Hoxn2ElNHThXJX7ixgxVpa7n+UyU2Q33Y/Pw3vO5vkAkbF4P9vjjqf34mWMykpGdMI0JSsYoKRS3jNrmSsfoOkxydxb6gKGHx3t9zYOm3+raWhkp9CTl68XfMqT3J3BHPMXVwNaFfxWrnYA1NTXeI2R1KcGwtExza84Y9kcNtSalo7IUyKKXbBNN532ae3ebDRLcQosYuYYi1mvTru0kr+A+jPF8Uid6sK9R7gFqpID3rS9Izv9RR64cDOr3oOyaMnaVvmuwdTEr58U7LYp8yQVF4qJrJKDlBRuEJre/rZuI5RMwW8yqvGiav1MaJILfG29aRO/VlDylW1SI+ubGQyp8cKty+OxQEQfdLg0qmFu31x7hOFsmn3TwDEpBZ2LP35TTm+IZgLUiAAiTv+aN5wAsGycUqtSibnpwqILWZQO6bedxedZuqPzVTtHy3mPgpYHFAeAe2Wcexn5pAAKVKTYjHeJ3yAH5EjnR9KIv+coiPqCmr5PsuWWEPDaABhc4lTfm0L3B9Id5D/fFy8GKwhRzHYRF4WMu1lFoFr8z+isAOK1pWk0+tSncDZSN7y8pFs0iYvV17hKg7Wxw1chHzRgR0MGAxqYX1vcEE/WjZ1GKSqJXMiuAtAt81Aupa/laQx1t+o7REyNKR4tVFbDi/Be/hkSwZHSo+08tPRdleRgWI+9d63n491bA19vwNtbGlbLmchOeIWSx9arqo/7+zvkYh7RUeIGAlszJZWtJhtB0X1vOm3x5Dm9yFtTM2GzmFzmfZP5NEO6nW0j0cKP6QBSN8DTFv5078zE+Mjht/NrFbH5f0cQYku/goeXVV3USYgnkpkTQ8GLwyeOvISlpNGCrxyK+4XFX9hFFhAFUDQVv9yG5o7kRAwYzPvThafANjTxPKfjyJ99bJ3O9iK/7hkUhWXzluEk8xKQRUqjY2nYtnUA+Ij1xqTVHbA0cJ6lrGJrmzcnIMM7zC8bSxp7G5hIvFJ/k842vKW5o7z9wCVFT/F9uNrrz29ApmeE/C3cYFZWsVl0rPknJ1F9mV90wObsEr0Utz6w+3kApShDUCPXr68ThoP1gResgsH7X/fdBs1KDSqPDd6oukTdlW0+5pbs5ufU8JJTo/lPZNf/dh7vpK3qpsrZaU15efqmjSPhTdNX+Xdvuoof9Bo+UaO+fvBKCisYKKuorTAu8TFugWeDo7JhuASyWXiD4cTWFNYb97QSI5Mplgj2DtUdv2QHLLcsN0BZPDyw8tH2ivyBzR5tQPgPVAHCkBwwOWJMxMwN/Jvz++JEV+VT5xJ+O4Xno9hY9Zyjrjr8n9BZgrIDj0rxSgqQOOArEdX5MzYCC9KDmQdDXDDDPMMMMMM8wwwwzj+B90i6eg5MMq6AAAAABJRU5ErkJggg==
  15. // @grant none
  16. // @require https://update.greasyfork.org/scripts/389765/1090053/CommonUtils.js
  17. // @require https://update.greasyfork.org/scripts/450160/1218867/WME-Bootstrap.js
  18. // @require https://update.greasyfork.org/scripts/452563/1218878/WME.js
  19. // @require https://update.greasyfork.org/scripts/450221/1137043/WME-Base.js
  20. // @require https://update.greasyfork.org/scripts/450320/1555446/WME-UI.js
  21. // ==/UserScript==
  22.  
  23. /* jshint esversion: 8 */
  24. /* global require */
  25. /* global $, jQuery */
  26. /* global W */
  27. /* global I18n */
  28. /* global WME, WMEBase, WMEUI, WMEUIHelper, WMEUIShortcut, WMEUIHelperControlButton */
  29. /* global Container, Settings, SimpleCache, Tools */
  30.  
  31. (function () {
  32. 'use strict'
  33.  
  34. // Script name, uses as unique index
  35. const NAME = 'E95'
  36.  
  37. // Translations
  38. const TRANSLATION = {
  39. 'en': {
  40. title: 'Quick Properties',
  41. description: 'Apply the road\'s settings by one click',
  42. help: 'You can use the <a href="#keyboard-dialog" target="_blank" rel="noopener noreferrer" data-toggle="modal">Keyboard shortcuts</a> to apply the settings. It\'s more convenient than clicking on the buttons.',
  43. },
  44. 'uk': {
  45. title: 'Швидкі налаштування',
  46. description: 'Застосовуйте швидкі налаштування для доріг за один клік',
  47. help: 'Використовуйте <a href="#keyboard-dialog" target="_blank" rel="noopener noreferrer" data-toggle="modal">гарячі клавіши</a>, це значно швидше ніж використовувати кнопку',
  48.  
  49. },
  50. 'ru': {
  51. title: 'Быстрые настройки',
  52. description: 'Применяйте быстрые настройки для дорог в один клик',
  53. help: 'Используйте <a href="#keyboard-dialog" target="_blank" rel="noopener noreferrer" data-toggle="modal">комбинации клавиш</a>, и не надо будет клацать кнопку',
  54. }
  55. }
  56.  
  57. const STYLE = 'button.waze-btn.E95 { margin: 0 4px 4px 0; padding: 2px; width: 42px; } ' +
  58. 'button.waze-btn.E95:hover { box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1), inset 0 0 100px 100px rgba(255, 255, 255, 0.3); } ' +
  59. 'button.waze-btn.E95-E { margin-right: 42px; }' +
  60. 'button.waze-btn.E95-J { margin-right: 42px; }' +
  61. 'p.e95-info { border-top: 1px solid #ccc; color: #777; font-size: x-small; margin-top: 15px; padding-top: 10px; text-align: center; }'
  62.  
  63.  
  64. WMEUI.addTranslation(NAME, TRANSLATION)
  65. WMEUI.addStyle(STYLE)
  66.  
  67. // Road Types
  68. // I18n.translations.uk.segment.road_types
  69. // I18n.translations.en.segment.road_types
  70. const TYPES = {
  71. street: 1,
  72. primary: 2,
  73. freeway: 3,
  74. ramp: 4,
  75. trail: 5,
  76. major: 6,
  77. minor: 7,
  78. offroad: 8,
  79. walkway: 9,
  80. boardwalk: 10,
  81. ferry: 15,
  82. stairway: 16,
  83. private: 17,
  84. railroad: 18,
  85. runway: 19,
  86. parking: 20,
  87. narrow: 22
  88. }
  89. // Road colors by type
  90. const COLORS = {
  91. '1': '#ffffeb',
  92. '2': '#f0ea58',
  93. // ...
  94. '8': '#867342',
  95. // ...
  96. '17': '#beba6c',
  97. // ...
  98. '20': '#ababab'
  99. }
  100. // Road Flags
  101. // for setup flags use binary operators
  102. // e.g. flags.tunnel | flags.headlights
  103. const FLAGS = {
  104. tunnel: 0b00000001,
  105. // ???
  106. // a : 0b00000010,
  107. // b : 0b00000100,
  108. // c : 0b00001000,
  109. unpaved: 0b00010000,
  110. headlights: 0b00100000,
  111. }
  112. // Buttons:
  113. // title - for buttons
  114. // shortcut - keys for shortcuts, by default is Alt + (1..9)
  115. // options:
  116. // - detectCity - try to detect the city name by closures segments
  117. // - clearCity - clear the city name
  118. // - clearStreet - clear the street name
  119. // attributes - native settings for model object
  120. // TODO:
  121. // – check permissions for user level lower than 2
  122. const BUTTONS = {
  123. A: {
  124. title: 'PR 5',
  125. shortcut: 'A+1',
  126. options: {
  127. detectCity: true,
  128. },
  129. attributes: {
  130. flags: 0,
  131. fwdMaxSpeed: 5,
  132. revMaxSpeed: 5,
  133. fwdMaxSpeedUnverified: false,
  134. revMaxSpeedUnverified: false,
  135. roadType: TYPES.private,
  136. lockRank: 0,
  137. }
  138. },
  139. B: {
  140. title: 'PR20',
  141. shortcut: 'A+2',
  142. options: {
  143. detectCity: true,
  144. },
  145. attributes: {
  146. flags: 0,
  147. fwdMaxSpeed: 20,
  148. revMaxSpeed: 20,
  149. fwdMaxSpeedUnverified: false,
  150. revMaxSpeedUnverified: false,
  151. roadType: TYPES.private,
  152. lockRank: 0,
  153. }
  154. },
  155. C: {
  156. title: 'PR50',
  157. shortcut: 'A+3',
  158. options: {
  159. detectCity: true,
  160. },
  161. attributes: {
  162. flags: 0,
  163. fwdMaxSpeed: 50,
  164. revMaxSpeed: 50,
  165. fwdMaxSpeedUnverified: false,
  166. revMaxSpeedUnverified: false,
  167. roadType: TYPES.private,
  168. lockRank: 0,
  169. }
  170. },
  171. D: {
  172. title: 'St50',
  173. shortcut: 'A+4',
  174. options: {
  175. detectCity: true,
  176. },
  177. attributes: {
  178. flags: 0,
  179. fwdMaxSpeed: 50,
  180. revMaxSpeed: 50,
  181. fwdMaxSpeedUnverified: false,
  182. revMaxSpeedUnverified: false,
  183. roadType: TYPES.street,
  184. lockRank: 0,
  185. }
  186. },
  187. E: {
  188. title: 'PS50',
  189. shortcut: 'A+5',
  190. options: {
  191. detectCity: true,
  192. },
  193. attributes: {
  194. flags: 0,
  195. fwdMaxSpeed: 50,
  196. revMaxSpeed: 50,
  197. fwdMaxSpeedUnverified: false,
  198. revMaxSpeedUnverified: false,
  199. roadType: TYPES.primary,
  200. lockRank: 1,
  201. }
  202. },
  203. F: {
  204. title: 'PLR',
  205. shortcut: 'A+6',
  206. options: {
  207. detectCity: true,
  208. },
  209. attributes: {
  210. flags: 0,
  211. fwdMaxSpeed: 5,
  212. revMaxSpeed: 5,
  213. fwdMaxSpeedUnverified: false,
  214. revMaxSpeedUnverified: false,
  215. roadType: TYPES.parking,
  216. lockRank: 0,
  217. }
  218. },
  219. G: {
  220. title: 'OR',
  221. shortcut: 'A+7',
  222. options: {
  223. clearCity: true,
  224. clearStreet: false,
  225. },
  226. attributes: {
  227. flags: 0,
  228. fwdMaxSpeed: 90,
  229. revMaxSpeed: 90,
  230. fwdMaxSpeedUnverified: false,
  231. revMaxSpeedUnverified: false,
  232. roadType: TYPES.offroad,
  233. lockRank: 0,
  234. }
  235. },
  236. H: {
  237. title: 'PR90',
  238. shortcut: 'A+8',
  239. options: {
  240. clearCity: true,
  241. },
  242. attributes: {
  243. flags: 0,
  244. fwdMaxSpeed: 90,
  245. revMaxSpeed: 90,
  246. fwdMaxSpeedUnverified: false,
  247. revMaxSpeedUnverified: false,
  248. roadType: TYPES.private,
  249. lockRank: 0,
  250. }
  251. },
  252. I: {
  253. title: 'St90',
  254. shortcut: 'A+9',
  255. options: {
  256. clearCity: true,
  257. },
  258. attributes: {
  259. flags: 0,
  260. fwdMaxSpeed: 90,
  261. revMaxSpeed: 90,
  262. fwdMaxSpeedUnverified: false,
  263. revMaxSpeedUnverified: false,
  264. roadType: TYPES.street,
  265. lockRank: 0,
  266. }
  267. },
  268. J: {
  269. title: 'PS90',
  270. shortcut: 'A+0',
  271. options: {
  272. clearCity: true,
  273. },
  274. attributes: {
  275. flags: 0,
  276. fwdMaxSpeed: 90,
  277. revMaxSpeed: 90,
  278. fwdMaxSpeedUnverified: false,
  279. revMaxSpeedUnverified: false,
  280. roadType: TYPES.primary,
  281. lockRank: 1,
  282. }
  283. }
  284. }
  285.  
  286. // codes of countries
  287. const COUNTRIES = {
  288. ukraine: 232
  289. }
  290.  
  291. // country specified buttons config
  292. const CONFIGS = {
  293. // Ukraine
  294. 232: {
  295. G: {
  296. attributes: {
  297. flags: FLAGS.headlights
  298. }
  299. },
  300. H: {
  301. attributes: {
  302. flags: FLAGS.headlights
  303. }
  304. },
  305. I: {
  306. attributes: {
  307. flags: FLAGS.headlights
  308. }
  309. },
  310. J: {
  311. attributes: {
  312. flags: FLAGS.headlights
  313. }
  314. },
  315. }
  316. }
  317.  
  318. // Require Waze API
  319. let WazeActionUpdateObject
  320. let WazeActionUpdateFeatureAddress
  321.  
  322. class E95 extends WMEBase {
  323. constructor (name, buttons, config ) {
  324. super(name)
  325.  
  326. this.helper = new WMEUIHelper(name)
  327.  
  328. this.panel = null
  329. this.buttons = buttons
  330. this.config = config
  331.  
  332.  
  333. let tab = this.helper.createTab(
  334. I18n.t(name).title,
  335. {
  336. image: GM_info.script.icon
  337. }
  338. )
  339. tab.addText('description', I18n.t(name).description)
  340. tab.addDiv('text', I18n.t(name).help)
  341. tab.addText(
  342. 'info',
  343. '<a href="' + GM_info.scriptUpdateURL + '">' + GM_info.script.name + '</a> ' + GM_info.script.version
  344. )
  345. tab.inject()
  346. }
  347.  
  348. getPanel () {
  349. if (this.panel) {
  350. return this.panel
  351. }
  352.  
  353. // Build panel
  354. // Container for buttons
  355. let controls = document.createElement('div')
  356. controls.className = 'controls'
  357. // Create buttons
  358. for (let btn in this.buttons) {
  359. let config = this.getButtonConfig(btn)
  360. let title = config.title
  361. let color = COLORS[config.attributes.roadType]
  362. let description = config.title + ' - ' +
  363. I18n.t('segment.road_types')[config.attributes.roadType] + '; ' +
  364. I18n.t('edit.segment.fields.speed_limit') + ' ' +
  365. I18n.t('measurements.speed.km', { speed: config.attributes.fwdMaxSpeed })
  366.  
  367. let UIButton = new WMEUIHelperControlButton(
  368. NAME,
  369. btn,
  370. title,
  371. description,
  372. () => this.buttonCallback(config),
  373. config.shortcut
  374. )
  375. let button = UIButton.html()
  376. button.dataset[NAME] = btn
  377. button.style.backgroundColor = color
  378. controls.appendChild(button)
  379. }
  380. let label = document.createElement('label')
  381. label.className = 'control-label'
  382. label.innerText = I18n.t(NAME).title
  383.  
  384. this.panel = document.createElement('div')
  385. this.panel.className = 'form-group ' + NAME
  386. this.panel.appendChild(label)
  387. this.panel.appendChild(controls)
  388.  
  389. return this.panel
  390. }
  391.  
  392. // Get Button settings
  393. getButtonConfig (index) {
  394. // Load settings for current country by call method W.model.getTopCountry().getID()
  395. // Then mixed it with default settings by Tools.mergeDeep() method
  396. return Tools.mergeDeep(this.buttons[index], this.config[index])
  397. }
  398.  
  399. // Handler for Road buttons
  400. buttonCallback (button) {
  401. // Get all selected segments
  402. let segments = WME.getSelectedSegments()
  403.  
  404. // Try to detect city, if needed
  405. if (button.options.detectCity) {
  406. let cityName = null
  407. for (let i = 0, total = segments.length; i < total; i++) {
  408. cityName = this.detectCity(segments[i])
  409. if (cityName) {
  410. button.options.cityName = cityName
  411. break
  412. }
  413. }
  414. }
  415. for (let i = 0, total = segments.length; i < total; i++) {
  416. this.updateSegment(segments[i], button.options, button.attributes)
  417. }
  418. }
  419.  
  420. /**
  421. * Update segment attributes
  422. * @param {Object} segment
  423. * @param {Object} options
  424. * @param {Object} attributes
  425. */
  426. updateSegment (segment, options, attributes = {}) {
  427. // current segment address
  428. let addr = segment.getAddress()
  429.  
  430. // fill address information
  431. let address = {
  432. countryID: addr.getCountry()?.getID() || W.model.getTopCountry().getID(),
  433. stateID: addr.getState()?.getID() || W.model.getTopState().getID(),
  434. cityName: addr.getCity()?.getName() || '',
  435. streetName: addr.getStreet()?.getName() || '',
  436. }
  437. // options: detect city
  438. if (!address.cityName && options.detectCity && options.cityName) {
  439. this.log('detected city name "' + options.cityName + '"')
  440. address.cityName = options.cityName
  441. }
  442. // options: clear city
  443. if (options.clearCity) {
  444. this.log('clear city name')
  445. address.cityName = null
  446. }
  447. // options: clear street
  448. if (options.clearStreet) {
  449. this.log('clear street name')
  450. address.streetName = null
  451. }
  452. // set city flag
  453. address.emptyCity = (address.cityName === null)
  454. // set street flag
  455. address.emptyStreet = (address.streetName === null) || (address.streetName === '')
  456.  
  457.  
  458. let updateFeatureAddress = new WazeActionUpdateFeatureAddress(
  459. segment,
  460. address,
  461. {
  462. streetIDField: 'primaryStreetID'
  463. }
  464. )
  465.  
  466. // update segment's address
  467. W.model.actionManager.add(updateFeatureAddress)
  468.  
  469. // keep the current lock level if it is higher than in the config's attributes
  470. if (segment.attributes.lockRank > attributes.lockRank) {
  471. attributes.lockRank = segment.attributes.lockRank
  472. }
  473. // need more logs
  474. this.log('set road type to ' + I18n.t('segment.road_types')[attributes.roadType])
  475.  
  476. // update segment's properties
  477. let updateObject = new WazeActionUpdateObject(segment, attributes)
  478.  
  479. W.model.actionManager.add(updateObject)
  480. }
  481.  
  482. /**
  483. * Detect city name by connected segments
  484. * @param {Object} segment
  485. * @return {String|null}
  486. */
  487. detectCity (segment) {
  488. // check cityName of the segment
  489. if (segment.getAddress().getCity() && !segment.getAddress().getCity().isEmpty()) {
  490. return segment.getAddress().getCity().getName()
  491. }
  492.  
  493. // TODO: replace follow magic with methods getConnectedSegments() and getConnectedSegmentsByDirection()
  494. // W.selectionManager.getSelectedDataModelObjects()[0].getConnectedSegments().map(x => x.attributes.id)
  495. // W.selectionManager.getSelectedDataModelObjects()[0].getConnectedSegmentsByDirection().map(x => x.attributes.id)
  496. // when it will work
  497. // last check - 2023.11.20
  498.  
  499. // connected segments
  500. let connected = []
  501. connected = connected.concat(segment.getFromNode().getSegmentIds()) // segments from point A
  502. connected = connected.concat(segment.getToNode().getSegmentIds()) // segments from point B
  503. connected = connected.filter(id => id !== segment.getID()) // filter himself
  504.  
  505. // cities of the connected segments
  506. let cities = connected.map(id => W.model.segments.getObjectById(id).getAddress().getCity())
  507. cities = cities.filter(city => city) // filter segments w/out city
  508. cities = cities.map(city => city.getName()) // extract cities name
  509. cities = cities.filter(city => city) // filter empty city name
  510.  
  511. if (cities.length) {
  512. return cities.shift()
  513. }
  514. return null
  515. }
  516.  
  517. /**
  518. * Handler for `segment.wme` event
  519. * Create UI controls every time when updated DOM of sidebar
  520. * Uses native JS function for better performance
  521. *
  522. * @param {jQuery.Event} event
  523. * @param {HTMLElement} element
  524. * @param {W.model} model
  525. * @return {void}
  526. */
  527. onSegment (event, element, model) {
  528. // Skip for walking trails and blocked roads
  529. if (model.isWalkingRoadType()
  530. || model.isLockedByHigherRank()
  531. || !model.isGeometryEditable()
  532. ) {
  533. return
  534. }
  535.  
  536. // Panel can be already exists
  537. element.querySelector('div.form-group.E95') ||
  538. element.prepend(this.getPanel())
  539. }
  540.  
  541. /**
  542. * Handler for `segments.wme` event
  543. * Create UI controls every time when updated DOM of sidebar
  544. * Uses native JS function for better performance
  545. *
  546. * @param {jQuery.Event} event
  547. * @param {HTMLElement} element
  548. * @param {Array} models
  549. * @return {void}
  550. */
  551. onSegments (event, element, models) {
  552. // Skip for walking trails or locked roads
  553. if (models.filter((model) => model.isWalkingRoadType() || model.isLockedByHigherRank() || !model.isGeometryEditable()).length > 0) {
  554. element.querySelector('div.form-group.E95')?.remove()
  555. return
  556. }
  557. // Panel can be already exists
  558. element.querySelector('div.form-group.E95') ||
  559. element.prepend(this.getPanel())
  560. }
  561. }
  562.  
  563. $(document).on('bootstrap.wme', () => {
  564. // Require scripts
  565. WazeActionUpdateObject = require('Waze/Action/UpdateObject')
  566. WazeActionUpdateFeatureAddress = require('Waze/Action/UpdateFeatureAddress')
  567.  
  568. // check country configuration
  569. let country = W.model.getTopCountry()?.getID() || COUNTRIES.ukraine
  570. let config = CONFIGS[country] ? CONFIGS[country] : CONFIGS[COUNTRIES.ukraine]
  571.  
  572. new E95(NAME, BUTTONS, config)
  573.  
  574. WMEUIShortcut.setGroupTitle(NAME, I18n.t(NAME).title)
  575. })
  576. })()