@theia/core 1.27.0-next.9 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/README.md +6 -7
  2. package/i18n/nls.cs.json +52 -6
  3. package/i18n/nls.de.json +52 -6
  4. package/i18n/nls.es.json +52 -6
  5. package/i18n/nls.fr.json +52 -6
  6. package/i18n/nls.hu.json +55 -9
  7. package/i18n/nls.it.json +52 -6
  8. package/i18n/nls.ja.json +52 -6
  9. package/i18n/nls.json +52 -6
  10. package/i18n/nls.pl.json +52 -6
  11. package/i18n/nls.pt-br.json +52 -6
  12. package/i18n/nls.pt-pt.json +52 -6
  13. package/i18n/nls.ru.json +52 -6
  14. package/i18n/nls.zh-cn.json +52 -6
  15. package/lib/browser/color-application-contribution.d.ts +2 -2
  16. package/lib/browser/color-application-contribution.d.ts.map +1 -1
  17. package/lib/browser/color-application-contribution.js +15 -16
  18. package/lib/browser/color-application-contribution.js.map +1 -1
  19. package/lib/browser/color-registry.d.ts +0 -4
  20. package/lib/browser/color-registry.d.ts.map +1 -1
  21. package/lib/browser/color-registry.js +0 -14
  22. package/lib/browser/color-registry.js.map +1 -1
  23. package/lib/browser/common-frontend-contribution.d.ts +4 -0
  24. package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
  25. package/lib/browser/common-frontend-contribution.js +157 -163
  26. package/lib/browser/common-frontend-contribution.js.map +1 -1
  27. package/lib/browser/common-styling-participants.d.ts +28 -0
  28. package/lib/browser/common-styling-participants.d.ts.map +1 -0
  29. package/lib/browser/common-styling-participants.js +319 -0
  30. package/lib/browser/common-styling-participants.js.map +1 -0
  31. package/lib/browser/connection-status-service.d.ts.map +1 -1
  32. package/lib/browser/connection-status-service.js +2 -2
  33. package/lib/browser/connection-status-service.js.map +1 -1
  34. package/lib/browser/connection-status-service.spec.js +1 -2
  35. package/lib/browser/connection-status-service.spec.js.map +1 -1
  36. package/lib/browser/context-menu-renderer.d.ts +1 -5
  37. package/lib/browser/context-menu-renderer.d.ts.map +1 -1
  38. package/lib/browser/context-menu-renderer.js +10 -30
  39. package/lib/browser/context-menu-renderer.js.map +1 -1
  40. package/lib/browser/core-preferences.d.ts +1 -0
  41. package/lib/browser/core-preferences.d.ts.map +1 -1
  42. package/lib/browser/core-preferences.js +5 -0
  43. package/lib/browser/core-preferences.js.map +1 -1
  44. package/lib/browser/decoration-style.d.ts +1 -0
  45. package/lib/browser/decoration-style.d.ts.map +1 -1
  46. package/lib/browser/decoration-style.js +6 -2
  47. package/lib/browser/decoration-style.js.map +1 -1
  48. package/lib/browser/frontend-application-bindings.d.ts.map +1 -1
  49. package/lib/browser/frontend-application-bindings.js +1 -3
  50. package/lib/browser/frontend-application-bindings.js.map +1 -1
  51. package/lib/browser/frontend-application-config-provider.d.ts +1 -0
  52. package/lib/browser/frontend-application-config-provider.d.ts.map +1 -1
  53. package/lib/browser/frontend-application-config-provider.js +2 -1
  54. package/lib/browser/frontend-application-config-provider.js.map +1 -1
  55. package/lib/browser/frontend-application-module.d.ts.map +1 -1
  56. package/lib/browser/frontend-application-module.js +9 -3
  57. package/lib/browser/frontend-application-module.js.map +1 -1
  58. package/lib/browser/i18n/i18n-frontend-module.d.ts.map +1 -1
  59. package/lib/browser/i18n/i18n-frontend-module.js +2 -0
  60. package/lib/browser/i18n/i18n-frontend-module.js.map +1 -1
  61. package/lib/browser/i18n/language-quick-pick-service.d.ts +17 -0
  62. package/lib/browser/i18n/language-quick-pick-service.d.ts.map +1 -0
  63. package/lib/browser/i18n/language-quick-pick-service.js +142 -0
  64. package/lib/browser/i18n/language-quick-pick-service.js.map +1 -0
  65. package/lib/browser/index.d.ts +1 -0
  66. package/lib/browser/index.d.ts.map +1 -1
  67. package/lib/browser/index.js +1 -0
  68. package/lib/browser/index.js.map +1 -1
  69. package/lib/browser/keybinding.d.ts.map +1 -1
  70. package/lib/browser/keybinding.js +2 -1
  71. package/lib/browser/keybinding.js.map +1 -1
  72. package/lib/browser/keybinding.spec.js +18 -21
  73. package/lib/browser/keybinding.spec.js.map +1 -1
  74. package/lib/browser/label-provider.d.ts +0 -12
  75. package/lib/browser/label-provider.d.ts.map +1 -1
  76. package/lib/browser/label-provider.js +1 -13
  77. package/lib/browser/label-provider.js.map +1 -1
  78. package/lib/browser/logger-frontend-module.d.ts.map +1 -1
  79. package/lib/browser/logger-frontend-module.js +8 -1
  80. package/lib/browser/logger-frontend-module.js.map +1 -1
  81. package/lib/browser/messaging/ws-connection-provider.d.ts +5 -4
  82. package/lib/browser/messaging/ws-connection-provider.d.ts.map +1 -1
  83. package/lib/browser/messaging/ws-connection-provider.js +30 -23
  84. package/lib/browser/messaging/ws-connection-provider.js.map +1 -1
  85. package/lib/browser/preferences/preference-contribution.d.ts +2 -19
  86. package/lib/browser/preferences/preference-contribution.d.ts.map +1 -1
  87. package/lib/browser/preferences/preference-contribution.js +1 -24
  88. package/lib/browser/preferences/preference-contribution.js.map +1 -1
  89. package/lib/browser/preferences/preference-proxy.d.ts +0 -4
  90. package/lib/browser/preferences/preference-proxy.d.ts.map +1 -1
  91. package/lib/browser/preferences/preference-proxy.js.map +1 -1
  92. package/lib/browser/preferences/preference-proxy.spec.js +3 -102
  93. package/lib/browser/preferences/preference-proxy.spec.js.map +1 -1
  94. package/lib/browser/preferences/preference-schema-provider.spec.js +4 -3
  95. package/lib/browser/preferences/preference-schema-provider.spec.js.map +1 -1
  96. package/lib/browser/preferences/preference-service.spec.js +1 -2
  97. package/lib/browser/preferences/preference-service.spec.js.map +1 -1
  98. package/lib/browser/preferences/preference-validation-service.d.ts +2 -2
  99. package/lib/browser/preferences/preference-validation-service.d.ts.map +1 -1
  100. package/lib/browser/preferences/preference-validation-service.spec.js.map +1 -1
  101. package/lib/browser/preloader.d.ts.map +1 -1
  102. package/lib/browser/preloader.js +7 -1
  103. package/lib/browser/preloader.js.map +1 -1
  104. package/lib/browser/progress-status-bar-item.d.ts +1 -1
  105. package/lib/browser/progress-status-bar-item.d.ts.map +1 -1
  106. package/lib/browser/quick-input/quick-command-service.d.ts.map +1 -1
  107. package/lib/browser/quick-input/quick-command-service.js +2 -2
  108. package/lib/browser/quick-input/quick-command-service.js.map +1 -1
  109. package/lib/browser/saveable.d.ts.map +1 -1
  110. package/lib/browser/saveable.js +5 -4
  111. package/lib/browser/saveable.js.map +1 -1
  112. package/lib/browser/shell/application-shell.d.ts +4 -0
  113. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  114. package/lib/browser/shell/application-shell.js +42 -36
  115. package/lib/browser/shell/application-shell.js.map +1 -1
  116. package/lib/browser/shell/shell-layout-restorer.d.ts +2 -0
  117. package/lib/browser/shell/shell-layout-restorer.d.ts.map +1 -1
  118. package/lib/browser/shell/shell-layout-restorer.js +5 -1
  119. package/lib/browser/shell/shell-layout-restorer.js.map +1 -1
  120. package/lib/browser/shell/side-panel-handler.d.ts.map +1 -1
  121. package/lib/browser/shell/side-panel-handler.js +3 -2
  122. package/lib/browser/shell/side-panel-handler.js.map +1 -1
  123. package/lib/browser/shell/tab-bars.d.ts +4 -2
  124. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  125. package/lib/browser/shell/tab-bars.js +12 -4
  126. package/lib/browser/shell/tab-bars.js.map +1 -1
  127. package/lib/browser/source-tree/source-tree-widget.js +1 -1
  128. package/lib/browser/source-tree/source-tree-widget.js.map +1 -1
  129. package/lib/browser/source-tree/tree-source.d.ts +2 -1
  130. package/lib/browser/source-tree/tree-source.d.ts.map +1 -1
  131. package/lib/browser/source-tree/tree-source.js.map +1 -1
  132. package/lib/browser/styling-service.d.ts +26 -0
  133. package/lib/browser/styling-service.d.ts.map +1 -0
  134. package/lib/browser/styling-service.js +76 -0
  135. package/lib/browser/styling-service.js.map +1 -0
  136. package/lib/browser/theming.d.ts +4 -8
  137. package/lib/browser/theming.d.ts.map +1 -1
  138. package/lib/browser/theming.js +38 -53
  139. package/lib/browser/theming.js.map +1 -1
  140. package/lib/browser/tree/search-box.d.ts.map +1 -1
  141. package/lib/browser/tree/search-box.js +5 -4
  142. package/lib/browser/tree/search-box.js.map +1 -1
  143. package/lib/browser/tree/test/tree-test-container.d.ts.map +1 -1
  144. package/lib/browser/tree/test/tree-test-container.js +2 -0
  145. package/lib/browser/tree/test/tree-test-container.js.map +1 -1
  146. package/lib/browser/tree/tree-compression/compressed-tree-model.d.ts +1 -1
  147. package/lib/browser/tree/tree-compression/compressed-tree-model.d.ts.map +1 -1
  148. package/lib/browser/tree/tree-compression/compressed-tree-model.js +4 -2
  149. package/lib/browser/tree/tree-compression/compressed-tree-model.js.map +1 -1
  150. package/lib/browser/tree/tree-compression/compressed-tree-widget.d.ts.map +1 -1
  151. package/lib/browser/tree/tree-compression/compressed-tree-widget.js +4 -2
  152. package/lib/browser/tree/tree-compression/compressed-tree-widget.js.map +1 -1
  153. package/lib/browser/tree/tree-container.d.ts +2 -0
  154. package/lib/browser/tree/tree-container.d.ts.map +1 -1
  155. package/lib/browser/tree/tree-container.js +3 -0
  156. package/lib/browser/tree/tree-container.js.map +1 -1
  157. package/lib/browser/tree/tree-focus-service.d.ts +20 -0
  158. package/lib/browser/tree/tree-focus-service.d.ts.map +1 -0
  159. package/lib/browser/tree/tree-focus-service.js +62 -0
  160. package/lib/browser/tree/tree-focus-service.js.map +1 -0
  161. package/lib/browser/tree/tree-model.d.ts +11 -2
  162. package/lib/browser/tree/tree-model.d.ts.map +1 -1
  163. package/lib/browser/tree/tree-model.js +29 -8
  164. package/lib/browser/tree/tree-model.js.map +1 -1
  165. package/lib/browser/tree/tree-selection-impl.d.ts +4 -1
  166. package/lib/browser/tree/tree-selection-impl.d.ts.map +1 -1
  167. package/lib/browser/tree/tree-selection-impl.js +13 -2
  168. package/lib/browser/tree/tree-selection-impl.js.map +1 -1
  169. package/lib/browser/tree/tree-selection-state.d.ts +1 -0
  170. package/lib/browser/tree/tree-selection-state.d.ts.map +1 -1
  171. package/lib/browser/tree/tree-selection-state.js +8 -2
  172. package/lib/browser/tree/tree-selection-state.js.map +1 -1
  173. package/lib/browser/tree/tree-selection.d.ts +9 -0
  174. package/lib/browser/tree/tree-selection.d.ts.map +1 -1
  175. package/lib/browser/tree/tree-selection.js +3 -0
  176. package/lib/browser/tree/tree-selection.js.map +1 -1
  177. package/lib/browser/tree/tree-widget-selection.d.ts.map +1 -1
  178. package/lib/browser/tree/tree-widget-selection.js +9 -1
  179. package/lib/browser/tree/tree-widget-selection.js.map +1 -1
  180. package/lib/browser/tree/tree-widget.d.ts +14 -0
  181. package/lib/browser/tree/tree-widget.d.ts.map +1 -1
  182. package/lib/browser/tree/tree-widget.js +80 -40
  183. package/lib/browser/tree/tree-widget.js.map +1 -1
  184. package/lib/browser/tree/tree.d.ts +2 -1
  185. package/lib/browser/tree/tree.d.ts.map +1 -1
  186. package/lib/browser/tree/tree.js +12 -2
  187. package/lib/browser/tree/tree.js.map +1 -1
  188. package/lib/browser/view-container.d.ts +9 -4
  189. package/lib/browser/view-container.d.ts.map +1 -1
  190. package/lib/browser/view-container.js +36 -6
  191. package/lib/browser/view-container.js.map +1 -1
  192. package/lib/common/cancellation.d.ts +1 -0
  193. package/lib/common/cancellation.d.ts.map +1 -1
  194. package/lib/common/cancellation.js +8 -0
  195. package/lib/common/cancellation.js.map +1 -1
  196. package/lib/common/command.d.ts +1 -1
  197. package/lib/common/command.d.ts.map +1 -1
  198. package/lib/common/command.js +13 -16
  199. package/lib/common/command.js.map +1 -1
  200. package/lib/common/index.d.ts +1 -0
  201. package/lib/common/index.d.ts.map +1 -1
  202. package/lib/common/index.js +1 -0
  203. package/lib/common/index.js.map +1 -1
  204. package/lib/common/message-rpc/channel.d.ts +106 -0
  205. package/lib/common/message-rpc/channel.d.ts.map +1 -0
  206. package/lib/common/message-rpc/channel.js +195 -0
  207. package/lib/common/message-rpc/channel.js.map +1 -0
  208. package/lib/common/message-rpc/channel.spec.d.ts +9 -0
  209. package/lib/common/message-rpc/channel.spec.d.ts.map +1 -0
  210. package/lib/common/message-rpc/channel.spec.js +80 -0
  211. package/lib/common/message-rpc/channel.spec.js.map +1 -0
  212. package/lib/common/message-rpc/index.d.ts +4 -0
  213. package/lib/common/message-rpc/index.d.ts.map +1 -0
  214. package/lib/{node/messaging/logger.js → common/message-rpc/index.js} +6 -19
  215. package/lib/common/message-rpc/index.js.map +1 -0
  216. package/lib/common/message-rpc/message-buffer.d.ts +50 -0
  217. package/lib/common/message-rpc/message-buffer.d.ts.map +1 -0
  218. package/lib/common/message-rpc/message-buffer.js +56 -0
  219. package/lib/common/message-rpc/message-buffer.js.map +1 -0
  220. package/lib/common/message-rpc/rpc-message-encoder.d.ts +171 -0
  221. package/lib/common/message-rpc/rpc-message-encoder.d.ts.map +1 -0
  222. package/lib/common/message-rpc/rpc-message-encoder.js +409 -0
  223. package/lib/common/message-rpc/rpc-message-encoder.js.map +1 -0
  224. package/lib/common/message-rpc/rpc-message-encoder.spec.d.ts +2 -0
  225. package/lib/common/message-rpc/rpc-message-encoder.spec.d.ts.map +1 -0
  226. package/lib/common/message-rpc/rpc-message-encoder.spec.js +49 -0
  227. package/lib/common/message-rpc/rpc-message-encoder.spec.js.map +1 -0
  228. package/lib/common/message-rpc/rpc-protocol.d.ts +61 -0
  229. package/lib/common/message-rpc/rpc-protocol.d.ts.map +1 -0
  230. package/lib/common/message-rpc/rpc-protocol.js +183 -0
  231. package/lib/common/message-rpc/rpc-protocol.js.map +1 -0
  232. package/lib/common/message-rpc/uint8-array-message-buffer.d.ts +52 -0
  233. package/lib/common/message-rpc/uint8-array-message-buffer.d.ts.map +1 -0
  234. package/lib/common/message-rpc/uint8-array-message-buffer.js +169 -0
  235. package/lib/common/message-rpc/uint8-array-message-buffer.js.map +1 -0
  236. package/lib/common/message-rpc/uint8-array-message-buffer.spec.d.ts +2 -0
  237. package/lib/common/message-rpc/uint8-array-message-buffer.spec.d.ts.map +1 -0
  238. package/lib/common/message-rpc/uint8-array-message-buffer.spec.js +39 -0
  239. package/lib/common/message-rpc/uint8-array-message-buffer.spec.js.map +1 -0
  240. package/lib/common/messaging/abstract-connection-provider.d.ts +9 -8
  241. package/lib/common/messaging/abstract-connection-provider.d.ts.map +1 -1
  242. package/lib/common/messaging/abstract-connection-provider.js +20 -35
  243. package/lib/common/messaging/abstract-connection-provider.js.map +1 -1
  244. package/lib/common/messaging/connection-error-handler.d.ts +1 -2
  245. package/lib/common/messaging/connection-error-handler.d.ts.map +1 -1
  246. package/lib/common/messaging/connection-error-handler.js +1 -1
  247. package/lib/common/messaging/connection-error-handler.js.map +1 -1
  248. package/lib/common/messaging/handler.d.ts +2 -2
  249. package/lib/common/messaging/handler.d.ts.map +1 -1
  250. package/lib/common/messaging/proxy-factory.d.ts +13 -7
  251. package/lib/common/messaging/proxy-factory.d.ts.map +1 -1
  252. package/lib/common/messaging/proxy-factory.js +18 -13
  253. package/lib/common/messaging/proxy-factory.js.map +1 -1
  254. package/lib/common/messaging/proxy-factory.spec.js +4 -15
  255. package/lib/common/messaging/proxy-factory.spec.js.map +1 -1
  256. package/lib/common/messaging/web-socket-channel.d.ts +54 -48
  257. package/lib/common/messaging/web-socket-channel.d.ts.map +1 -1
  258. package/lib/common/messaging/web-socket-channel.js +41 -105
  259. package/lib/common/messaging/web-socket-channel.js.map +1 -1
  260. package/lib/common/nls.d.ts +2 -0
  261. package/lib/common/nls.d.ts.map +1 -1
  262. package/lib/common/nls.js +11 -0
  263. package/lib/common/nls.js.map +1 -1
  264. package/lib/common/preferences/preference-schema.d.ts +1 -5
  265. package/lib/common/preferences/preference-schema.d.ts.map +1 -1
  266. package/lib/common/preferences/preference-schema.js.map +1 -1
  267. package/lib/common/promise-util.d.ts +2 -1
  268. package/lib/common/promise-util.d.ts.map +1 -1
  269. package/lib/common/promise-util.js +8 -13
  270. package/lib/common/promise-util.js.map +1 -1
  271. package/lib/common/resource.d.ts +5 -0
  272. package/lib/common/resource.d.ts.map +1 -1
  273. package/lib/common/resource.js +28 -1
  274. package/lib/common/resource.js.map +1 -1
  275. package/lib/common/theme.d.ts +3 -2
  276. package/lib/common/theme.d.ts.map +1 -1
  277. package/lib/common/theme.js +5 -0
  278. package/lib/common/theme.js.map +1 -1
  279. package/lib/electron-browser/messaging/electron-ipc-connection-provider.d.ts +2 -2
  280. package/lib/electron-browser/messaging/electron-ipc-connection-provider.d.ts.map +1 -1
  281. package/lib/electron-browser/messaging/electron-ipc-connection-provider.js +18 -7
  282. package/lib/electron-browser/messaging/electron-ipc-connection-provider.js.map +1 -1
  283. package/lib/electron-browser/messaging/electron-ws-connection-provider.d.ts +2 -2
  284. package/lib/electron-browser/messaging/electron-ws-connection-provider.d.ts.map +1 -1
  285. package/lib/electron-browser/messaging/electron-ws-connection-provider.js +5 -7
  286. package/lib/electron-browser/messaging/electron-ws-connection-provider.js.map +1 -1
  287. package/lib/electron-main/event-utils.d.ts +1 -1
  288. package/lib/electron-main/messaging/electron-messaging-contribution.d.ts +37 -9
  289. package/lib/electron-main/messaging/electron-messaging-contribution.d.ts.map +1 -1
  290. package/lib/electron-main/messaging/electron-messaging-contribution.js +83 -68
  291. package/lib/electron-main/messaging/electron-messaging-contribution.js.map +1 -1
  292. package/lib/electron-main/messaging/electron-messaging-service.d.ts +2 -8
  293. package/lib/electron-main/messaging/electron-messaging-service.d.ts.map +1 -1
  294. package/lib/electron-main/messaging/electron-messaging-service.js.map +1 -1
  295. package/lib/node/messaging/binary-message-pipe.d.ts +45 -0
  296. package/lib/node/messaging/binary-message-pipe.d.ts.map +1 -0
  297. package/lib/node/messaging/binary-message-pipe.js +152 -0
  298. package/lib/node/messaging/binary-message-pipe.js.map +1 -0
  299. package/lib/node/messaging/ipc-bootstrap.js +2 -11
  300. package/lib/node/messaging/ipc-bootstrap.js.map +1 -1
  301. package/lib/node/messaging/ipc-channel.d.ts +26 -0
  302. package/lib/node/messaging/ipc-channel.d.ts.map +1 -0
  303. package/lib/node/messaging/ipc-channel.js +86 -0
  304. package/lib/node/messaging/ipc-channel.js.map +1 -0
  305. package/lib/node/messaging/ipc-connection-provider.d.ts +3 -5
  306. package/lib/node/messaging/ipc-connection-provider.d.ts.map +1 -1
  307. package/lib/node/messaging/ipc-connection-provider.js +14 -31
  308. package/lib/node/messaging/ipc-connection-provider.js.map +1 -1
  309. package/lib/node/messaging/ipc-protocol.d.ts +2 -2
  310. package/lib/node/messaging/ipc-protocol.d.ts.map +1 -1
  311. package/lib/node/messaging/messaging-contribution.d.ts +6 -9
  312. package/lib/node/messaging/messaging-contribution.d.ts.map +1 -1
  313. package/lib/node/messaging/messaging-contribution.js +23 -68
  314. package/lib/node/messaging/messaging-contribution.js.map +1 -1
  315. package/lib/node/messaging/messaging-service.d.ts +4 -23
  316. package/lib/node/messaging/messaging-service.d.ts.map +1 -1
  317. package/lib/node/messaging/messaging-service.js +1 -15
  318. package/lib/node/messaging/messaging-service.js.map +1 -1
  319. package/lib/node/messaging/test/test-web-socket-channel.d.ts +4 -2
  320. package/lib/node/messaging/test/test-web-socket-channel.d.ts.map +1 -1
  321. package/lib/node/messaging/test/test-web-socket-channel.js +25 -12
  322. package/lib/node/messaging/test/test-web-socket-channel.js.map +1 -1
  323. package/lib/node/request/proxy-cli-contribution.js +1 -1
  324. package/lib/node/request/proxy-cli-contribution.js.map +1 -1
  325. package/package.json +7 -10
  326. package/src/browser/color-application-contribution.ts +10 -17
  327. package/src/browser/color-registry.ts +0 -5
  328. package/src/browser/common-frontend-contribution.ts +26 -33
  329. package/src/browser/common-styling-participants.ts +307 -0
  330. package/src/browser/connection-status-service.spec.ts +1 -4
  331. package/src/browser/connection-status-service.ts +3 -3
  332. package/src/browser/context-menu-renderer.ts +13 -29
  333. package/src/browser/core-preferences.ts +6 -0
  334. package/src/browser/decoration-style.ts +6 -2
  335. package/src/browser/frontend-application-bindings.ts +1 -3
  336. package/src/browser/frontend-application-config-provider.ts +2 -0
  337. package/src/browser/frontend-application-module.ts +11 -4
  338. package/src/browser/i18n/i18n-frontend-module.ts +2 -0
  339. package/src/browser/i18n/language-quick-pick-service.ts +128 -0
  340. package/src/browser/index.ts +1 -0
  341. package/src/browser/keybinding.spec.ts +22 -27
  342. package/src/browser/keybinding.ts +2 -1
  343. package/src/browser/label-provider.ts +0 -13
  344. package/src/browser/logger-frontend-module.ts +8 -1
  345. package/src/browser/messaging/ws-connection-provider.ts +34 -25
  346. package/src/browser/preferences/preference-contribution.ts +3 -28
  347. package/src/browser/preferences/preference-proxy.spec.ts +3 -113
  348. package/src/browser/preferences/preference-proxy.ts +0 -4
  349. package/src/browser/preferences/preference-schema-provider.spec.ts +1 -4
  350. package/src/browser/preferences/preference-service.spec.ts +1 -5
  351. package/src/browser/preferences/preference-validation-service.spec.ts +2 -2
  352. package/src/browser/preferences/preference-validation-service.ts +2 -2
  353. package/src/browser/preloader.ts +9 -2
  354. package/src/browser/progress-status-bar-item.ts +1 -1
  355. package/src/browser/quick-input/quick-command-service.ts +3 -3
  356. package/src/browser/saveable.ts +5 -4
  357. package/src/browser/shell/application-shell.ts +42 -35
  358. package/src/browser/shell/shell-layout-restorer.ts +4 -6
  359. package/src/browser/shell/side-panel-handler.ts +3 -2
  360. package/src/browser/shell/tab-bars.ts +14 -4
  361. package/src/browser/source-tree/source-tree-widget.tsx +1 -1
  362. package/src/browser/source-tree/tree-source.ts +2 -1
  363. package/src/browser/style/breadcrumbs.css +0 -1
  364. package/src/browser/style/index.css +66 -29
  365. package/src/browser/style/menus.css +4 -2
  366. package/src/browser/style/select-component.css +2 -0
  367. package/src/browser/style/sidepanel.css +11 -25
  368. package/src/browser/style/status-bar.css +8 -17
  369. package/src/browser/style/tabs.css +0 -16
  370. package/src/browser/style/tooltip.css +3 -3
  371. package/src/browser/style/tree.css +27 -11
  372. package/src/browser/style/view-container.css +4 -0
  373. package/src/browser/styling-service.ts +76 -0
  374. package/src/browser/theming.ts +18 -45
  375. package/src/browser/tree/search-box.ts +5 -4
  376. package/src/browser/tree/test/tree-test-container.ts +2 -0
  377. package/src/browser/tree/tree-compression/compressed-tree-model.ts +8 -2
  378. package/src/browser/tree/tree-compression/compressed-tree-widget.tsx +4 -2
  379. package/src/browser/tree/tree-container.ts +4 -0
  380. package/src/browser/tree/tree-focus-service.ts +55 -0
  381. package/src/browser/tree/tree-model.ts +32 -8
  382. package/src/browser/tree/tree-selection-impl.ts +13 -4
  383. package/src/browser/tree/tree-selection-state.ts +7 -2
  384. package/src/browser/tree/tree-selection.ts +10 -0
  385. package/src/browser/tree/tree-widget-selection.ts +10 -1
  386. package/src/browser/tree/tree-widget.tsx +83 -43
  387. package/src/browser/tree/tree.ts +8 -2
  388. package/src/browser/view-container.ts +41 -4
  389. package/src/common/cancellation.ts +8 -0
  390. package/src/common/command.ts +14 -16
  391. package/src/common/index.ts +1 -0
  392. package/src/common/message-rpc/channel.spec.ts +88 -0
  393. package/src/common/message-rpc/channel.ts +260 -0
  394. package/src/{node/messaging/logger.ts → common/message-rpc/index.ts} +4 -23
  395. package/src/common/message-rpc/message-buffer.ts +99 -0
  396. package/src/common/message-rpc/rpc-message-encoder.spec.ts +55 -0
  397. package/src/common/message-rpc/rpc-message-encoder.ts +552 -0
  398. package/src/common/message-rpc/rpc-protocol.ts +217 -0
  399. package/src/common/message-rpc/uint8-array-message-buffer.spec.ts +41 -0
  400. package/src/common/message-rpc/uint8-array-message-buffer.ts +206 -0
  401. package/src/common/messaging/abstract-connection-provider.ts +28 -37
  402. package/src/common/messaging/connection-error-handler.ts +1 -2
  403. package/src/common/messaging/handler.ts +2 -2
  404. package/src/common/messaging/proxy-factory.spec.ts +4 -17
  405. package/src/common/messaging/proxy-factory.ts +27 -16
  406. package/src/common/messaging/web-socket-channel.ts +79 -135
  407. package/src/common/nls.ts +11 -0
  408. package/src/common/preferences/preference-schema.ts +1 -6
  409. package/src/common/promise-util.ts +13 -14
  410. package/src/common/resource.ts +29 -2
  411. package/src/common/theme.ts +6 -2
  412. package/src/electron-browser/messaging/electron-ipc-connection-provider.ts +21 -7
  413. package/src/electron-browser/messaging/electron-ws-connection-provider.ts +5 -8
  414. package/src/electron-main/messaging/electron-messaging-contribution.ts +87 -65
  415. package/src/electron-main/messaging/electron-messaging-service.ts +2 -8
  416. package/src/node/messaging/binary-message-pipe.ts +168 -0
  417. package/src/node/messaging/ipc-bootstrap.ts +3 -11
  418. package/src/node/messaging/ipc-channel.ts +97 -0
  419. package/src/node/messaging/ipc-connection-provider.ts +18 -35
  420. package/src/node/messaging/ipc-protocol.ts +2 -2
  421. package/src/node/messaging/messaging-contribution.ts +29 -74
  422. package/src/node/messaging/messaging-service.ts +4 -31
  423. package/src/node/messaging/test/test-web-socket-channel.ts +26 -17
  424. package/src/node/request/proxy-cli-contribution.ts +1 -1
  425. package/lib/browser/preferences/validated-preference-proxy.d.ts +0 -21
  426. package/lib/browser/preferences/validated-preference-proxy.d.ts.map +0 -1
  427. package/lib/browser/preferences/validated-preference-proxy.js +0 -118
  428. package/lib/browser/preferences/validated-preference-proxy.js.map +0 -1
  429. package/lib/node/messaging/logger.d.ts +0 -8
  430. package/lib/node/messaging/logger.d.ts.map +0 -1
  431. package/lib/node/messaging/logger.js.map +0 -1
  432. package/shared/vscode-ws-jsonrpc/index.d.ts +0 -1
  433. package/shared/vscode-ws-jsonrpc/index.js +0 -1
  434. package/src/browser/preferences/validated-preference-proxy.ts +0 -111
  435. package/src/browser/style/variables-bright.useable.css +0 -93
  436. package/src/browser/style/variables-dark.useable.css +0 -93
@@ -38,8 +38,14 @@ export class CompressedTreeModel extends TreeModelImpl {
38
38
  @inject(CompressionToggle) protected readonly compressionToggle: CompressionToggle;
39
39
  @inject(TreeCompressionService) protected readonly compressionService: TreeCompressionService;
40
40
 
41
- protected selectAdjacentRow(direction: BackOrForward, type: TreeSelection.SelectionType = TreeSelection.SelectionType.DEFAULT): void {
42
- let startingPoint: TreeNode = this.selectedNodes[0];
41
+ protected selectAdjacentRow(
42
+ direction: BackOrForward,
43
+ type: TreeSelection.SelectionType = TreeSelection.SelectionType.DEFAULT,
44
+ startingPoint: Readonly<TreeNode> | undefined = this.getFocusedNode()
45
+ ): void {
46
+ if (!startingPoint && this.root) {
47
+ this.selectAdjacentRow(BackOrForward.Forward, type, this.root);
48
+ }
43
49
  if (this.compressionService.isCompressionParticipant(startingPoint)) {
44
50
  const chain = this.compressionService.getCompressionChain(startingPoint);
45
51
  startingPoint = (direction === BackOrForward.Backward ? chain?.head() : chain?.tail()) ?? startingPoint;
@@ -132,12 +132,14 @@ export class CompressedTreeWidget extends TreeViewWelcomeWidget {
132
132
  if (!this.compressionToggle.compress) { return super.handleUp(event); }
133
133
  const type = this.props.multiSelect && this.hasShiftMask(event) ? TreeSelection.SelectionType.RANGE : undefined;
134
134
  this.model.selectPrevRow(type);
135
+ this.node.focus();
135
136
  }
136
137
 
137
138
  protected override handleDown(event: KeyboardEvent): void {
138
139
  if (!this.compressionToggle.compress) { return super.handleDown(event); }
139
140
  const type = this.props.multiSelect && this.hasShiftMask(event) ? TreeSelection.SelectionType.RANGE : undefined;
140
141
  this.model.selectNextRow(type);
142
+ this.node.focus();
141
143
  }
142
144
 
143
145
  protected override async handleLeft(event: KeyboardEvent): Promise<void> {
@@ -145,7 +147,7 @@ export class CompressedTreeWidget extends TreeViewWelcomeWidget {
145
147
  if (Boolean(this.props.multiSelect) && (this.hasCtrlCmdMask(event) || this.hasShiftMask(event))) {
146
148
  return;
147
149
  }
148
- const active = this.model.selectedNodes[0];
150
+ const active = this.focusService.focusedNode;
149
151
  if (ExpandableTreeNode.isExpanded(active)
150
152
  && (
151
153
  this.compressionService.isCompressionHead(active)
@@ -162,7 +164,7 @@ export class CompressedTreeWidget extends TreeViewWelcomeWidget {
162
164
  if (Boolean(this.props.multiSelect) && (this.hasCtrlCmdMask(event) || this.hasShiftMask(event))) {
163
165
  return;
164
166
  }
165
- const active = this.model.selectedNodes[0];
167
+ const active = this.focusService.focusedNode;
166
168
 
167
169
  if (ExpandableTreeNode.isCollapsed(active)
168
170
  && (
@@ -27,6 +27,7 @@ import { TreeSearch } from './tree-search';
27
27
  import { FuzzySearch } from './fuzzy-search';
28
28
  import { SearchBox, SearchBoxFactory } from './search-box';
29
29
  import { SearchBoxDebounce } from './search-box-debounce';
30
+ import { TreeFocusService, TreeFocusServiceImpl } from './tree-focus-service';
30
31
 
31
32
  export function isTreeServices(candidate?: Partial<TreeProps> | Partial<TreeContainerProps>): candidate is TreeContainerProps {
32
33
  if (candidate) {
@@ -110,6 +111,7 @@ interface TreeServices {
110
111
  search: TreeSearch,
111
112
  fuzzy: FuzzySearch,
112
113
  decoratorService: TreeDecoratorService,
114
+ focusService: TreeFocusService,
113
115
  }
114
116
 
115
117
  interface TreeTypes extends TreeServices, TreeConstants { }
@@ -132,6 +134,7 @@ const defaultImplementations: TreeContainerProps & { props: TreeProps } = {
132
134
  search: TreeSearch,
133
135
  fuzzy: FuzzySearch,
134
136
  decoratorService: NoopTreeDecoratorService,
137
+ focusService: TreeFocusServiceImpl,
135
138
  props: defaultTreeProps,
136
139
  searchBoxFactory: defaultSearchBoxFactoryFactory,
137
140
  };
@@ -148,4 +151,5 @@ const serviceIdentifiers: TreeIdentifiers = {
148
151
  fuzzy: FuzzySearch,
149
152
  searchBoxFactory: SearchBoxFactory,
150
153
  decoratorService: TreeDecoratorService,
154
+ focusService: TreeFocusService
151
155
  };
@@ -0,0 +1,55 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2022 Ericsson and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { inject, injectable } from 'inversify';
18
+ import { Emitter, Event } from '../../common';
19
+ import { Tree, TreeNode } from './tree';
20
+ import { SelectableTreeNode } from './tree-selection';
21
+
22
+ export interface TreeFocusService {
23
+ readonly focusedNode: SelectableTreeNode | undefined;
24
+ readonly onDidChangeFocus: Event<SelectableTreeNode | undefined>;
25
+ setFocus(node?: SelectableTreeNode): void;
26
+ hasFocus(node?: TreeNode): boolean;
27
+ }
28
+ export const TreeFocusService = Symbol('TreeFocusService');
29
+
30
+ @injectable()
31
+ export class TreeFocusServiceImpl implements TreeFocusService {
32
+ protected focusedId: string | undefined;
33
+ protected onDidChangeFocusEmitter = new Emitter<SelectableTreeNode | undefined>();
34
+ get onDidChangeFocus(): Event<SelectableTreeNode | undefined> { return this.onDidChangeFocusEmitter.event; }
35
+
36
+ @inject(Tree) protected readonly tree: Tree;
37
+
38
+ get focusedNode(): SelectableTreeNode | undefined {
39
+ const candidate = this.tree.getNode(this.focusedId);
40
+ if (SelectableTreeNode.is(candidate)) {
41
+ return candidate;
42
+ }
43
+ }
44
+
45
+ setFocus(node?: SelectableTreeNode): void {
46
+ if (node?.id !== this.focusedId) {
47
+ this.focusedId = node?.id;
48
+ this.onDidChangeFocusEmitter.fire(node);
49
+ }
50
+ }
51
+
52
+ hasFocus(node?: TreeNode): boolean {
53
+ return !!node && node?.id === this.focusedId;
54
+ }
55
+ }
@@ -26,6 +26,7 @@ import { TreeExpansionService, ExpandableTreeNode } from './tree-expansion';
26
26
  import { TreeNavigationService } from './tree-navigation';
27
27
  import { TreeIterator, BottomUpTreeIterator, TopDownTreeIterator, Iterators } from './tree-iterator';
28
28
  import { TreeSearch } from './tree-search';
29
+ import { TreeFocusService } from './tree-focus-service';
29
30
 
30
31
  /**
31
32
  * The tree model.
@@ -134,6 +135,11 @@ export interface TreeModel extends Tree, TreeSelectionService, TreeExpansionServ
134
135
  * If no node was selected previously, invoking this method does nothing.
135
136
  */
136
137
  selectRange(node: Readonly<SelectableTreeNode>): void;
138
+
139
+ /**
140
+ * Returns the node currently in focus in this tree, or undefined if no node is focused.
141
+ */
142
+ getFocusedNode(): SelectableTreeNode | undefined
137
143
  }
138
144
 
139
145
  @injectable()
@@ -144,6 +150,7 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
144
150
  @inject(TreeSelectionService) protected readonly selectionService: TreeSelectionService;
145
151
  @inject(TreeExpansionService) protected readonly expansionService: TreeExpansionService;
146
152
  @inject(TreeNavigationService) protected readonly navigationService: TreeNavigationService;
153
+ @inject(TreeFocusService) protected readonly focusService: TreeFocusService;
147
154
  @inject(TreeSearch) protected readonly treeSearch: TreeSearch;
148
155
 
149
156
  protected readonly onChangedEmitter = new Emitter<void>();
@@ -215,6 +222,10 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
215
222
  return this.tree.getNode(id);
216
223
  }
217
224
 
225
+ getFocusedNode(): SelectableTreeNode | undefined {
226
+ return this.focusService.focusedNode;
227
+ }
228
+
218
229
  validateNode(node: TreeNode | undefined): TreeNode | undefined {
219
230
  return this.tree.validateNode(node);
220
231
  }
@@ -241,7 +252,7 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
241
252
  }
242
253
 
243
254
  async expandNode(raw?: Readonly<ExpandableTreeNode>): Promise<ExpandableTreeNode | undefined> {
244
- for (const node of raw ? [raw] : this.selectedNodes) {
255
+ for (const node of this.getExpansionCandidates(raw)) {
245
256
  if (ExpandableTreeNode.is(node)) {
246
257
  return this.expansionService.expandNode(node);
247
258
  }
@@ -249,8 +260,14 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
249
260
  return undefined;
250
261
  }
251
262
 
263
+ protected *getExpansionCandidates(raw?: Readonly<TreeNode>): IterableIterator<TreeNode | undefined> {
264
+ yield raw;
265
+ yield this.getFocusedNode();
266
+ yield* this.selectedNodes;
267
+ }
268
+
252
269
  async collapseNode(raw?: Readonly<ExpandableTreeNode>): Promise<boolean> {
253
- for (const node of raw ? [raw] : this.selectedNodes) {
270
+ for (const node of this.getExpansionCandidates(raw)) {
254
271
  if (ExpandableTreeNode.is(node)) {
255
272
  return this.expansionService.collapseNode(node);
256
273
  }
@@ -259,7 +276,7 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
259
276
  }
260
277
 
261
278
  async collapseAll(raw?: Readonly<CompositeTreeNode>): Promise<boolean> {
262
- const node = raw || this.selectedNodes[0];
279
+ const node = raw || this.getFocusedNode();
263
280
  if (SelectableTreeNode.is(node)) {
264
281
  this.selectNode(node);
265
282
  }
@@ -284,7 +301,10 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
284
301
  }
285
302
  }
286
303
 
287
- getPrevSelectableNode(node: TreeNode = this.selectedNodes[0]): SelectableTreeNode | undefined {
304
+ getPrevSelectableNode(node: TreeNode | undefined = this.getFocusedNode()): SelectableTreeNode | undefined {
305
+ if (!node) {
306
+ return this.getNextSelectableNode(this.root);
307
+ }
288
308
  const iterator = this.createBackwardIterator(node);
289
309
  return iterator && this.doGetNextNode(iterator, this.isVisibleSelectableNode.bind(this));
290
310
  }
@@ -296,7 +316,7 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
296
316
  }
297
317
  }
298
318
 
299
- getNextSelectableNode(node: TreeNode = this.selectedNodes[0]): SelectableTreeNode | undefined {
319
+ getNextSelectableNode(node: TreeNode | undefined = this.getFocusedNode() ?? this.root): SelectableTreeNode | undefined {
300
320
  const iterator = this.createIterator(node);
301
321
  return iterator && this.doGetNextNode(iterator, this.isVisibleSelectableNode.bind(this));
302
322
  }
@@ -345,7 +365,7 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
345
365
  }
346
366
 
347
367
  openNode(raw?: TreeNode | undefined): void {
348
- const node = raw || this.selectedNodes[0];
368
+ const node = raw ?? this.focusService.focusedNode;
349
369
  if (node) {
350
370
  this.doOpenNode(node);
351
371
  this.onOpenNodeEmitter.fire(node);
@@ -359,8 +379,8 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
359
379
  }
360
380
 
361
381
  selectParent(): void {
362
- if (this.selectedNodes.length === 1) {
363
- const node = this.selectedNodes[0];
382
+ const node = this.getFocusedNode();
383
+ if (node) {
364
384
  const parent = SelectableTreeNode.getVisibleParent(node);
365
385
  if (parent) {
366
386
  this.selectNode(parent);
@@ -416,6 +436,10 @@ export class TreeModelImpl implements TreeModel, SelectionProvider<ReadonlyArray
416
436
  this.selectionService.addSelection(selectionOrTreeNode);
417
437
  }
418
438
 
439
+ clearSelection(): void {
440
+ this.selectionService.clearSelection();
441
+ }
442
+
419
443
  selectNode(node: Readonly<SelectableTreeNode>): void {
420
444
  this.addSelection(node);
421
445
  }
@@ -19,12 +19,14 @@ import { Tree, TreeNode } from './tree';
19
19
  import { Event, Emitter } from '../../common';
20
20
  import { TreeSelectionState, FocusableTreeSelection } from './tree-selection-state';
21
21
  import { TreeSelectionService, SelectableTreeNode, TreeSelection } from './tree-selection';
22
+ import { TreeFocusService } from './tree-focus-service';
22
23
 
23
24
  @injectable()
24
25
  export class TreeSelectionServiceImpl implements TreeSelectionService {
25
26
 
26
- @inject(Tree)
27
- protected readonly tree: Tree;
27
+ @inject(Tree) protected readonly tree: Tree;
28
+ @inject(TreeFocusService) protected readonly focusService: TreeFocusService;
29
+
28
30
  protected readonly onSelectionChangedEmitter = new Emitter<ReadonlyArray<Readonly<SelectableTreeNode>>>();
29
31
 
30
32
  protected state: TreeSelectionState;
@@ -75,7 +77,11 @@ export class TreeSelectionServiceImpl implements TreeSelectionService {
75
77
  this.transiteTo(newState);
76
78
  }
77
79
 
78
- protected transiteTo(newState: TreeSelectionState): void {
80
+ clearSelection(): void {
81
+ this.transiteTo(new TreeSelectionState(this.tree), false);
82
+ }
83
+
84
+ protected transiteTo(newState: TreeSelectionState, setFocus = true): void {
79
85
  const oldNodes = this.state.selection();
80
86
  const newNodes = newState.selection();
81
87
 
@@ -85,7 +91,9 @@ export class TreeSelectionServiceImpl implements TreeSelectionService {
85
91
  this.unselect(toUnselect);
86
92
  this.select(toSelect);
87
93
  this.removeFocus(oldNodes, newNodes);
88
- this.addFocus(newState.focus);
94
+ if (setFocus) {
95
+ this.addFocus(newState.node);
96
+ }
89
97
 
90
98
  this.state = newState;
91
99
  this.fireSelectionChanged();
@@ -107,6 +115,7 @@ export class TreeSelectionServiceImpl implements TreeSelectionService {
107
115
  if (node) {
108
116
  node.focus = true;
109
117
  }
118
+ this.focusService.setFocus(node);
110
119
  }
111
120
 
112
121
  /**
@@ -95,10 +95,15 @@ export class TreeSelectionState {
95
95
 
96
96
  get focus(): SelectableTreeNode | undefined {
97
97
  const copy = this.checkNoDefaultSelection(this.selectionStack);
98
- const candidate = copy[copy.length - 1].focus;
98
+ const candidate = copy[copy.length - 1]?.focus;
99
99
  return this.toSelectableTreeNode(candidate);
100
100
  }
101
101
 
102
+ get node(): SelectableTreeNode | undefined {
103
+ const copy = this.checkNoDefaultSelection(this.selectionStack);
104
+ return this.toSelectableTreeNode(copy[copy.length - 1]?.node);
105
+ }
106
+
102
107
  protected handleDefault(state: TreeSelectionState, node: Readonly<SelectableTreeNode>): TreeSelectionState {
103
108
  const { tree } = state;
104
109
  return new TreeSelectionState(tree, [{
@@ -116,7 +121,7 @@ export class TreeSelectionState {
116
121
  for (let i = allRanges.length - 1; i >= 0; i--) {
117
122
  const latestRangeIndex = copy.indexOf(allRanges[i]);
118
123
  const latestRangeSelection = copy[latestRangeIndex];
119
- const latestRange = latestRangeSelection && latestRangeSelection.focus ? this.selectionRange(latestRangeSelection) : [];
124
+ const latestRange = latestRangeSelection?.focus ? this.selectionRange(latestRangeSelection) : [];
120
125
  if (latestRange.indexOf(node) !== -1) {
121
126
  if (this.focus === latestRangeSelection.focus) {
122
127
  return latestRangeSelection.focus || node;
@@ -41,6 +41,11 @@ export interface TreeSelectionService extends Disposable, SelectionProvider<Read
41
41
  */
42
42
  addSelection(selectionOrTreeNode: TreeSelection | Readonly<SelectableTreeNode>): void;
43
43
 
44
+ /**
45
+ * Clears all selected nodes
46
+ */
47
+ clearSelection(): void;
48
+
44
49
  /**
45
50
  * Store selection state.
46
51
  */
@@ -114,6 +119,8 @@ export interface SelectableTreeNode extends TreeNode {
114
119
  selected: boolean;
115
120
 
116
121
  /**
122
+ * @deprecated @since 1.27.0. Use TreeFocusService to track the focused node.
123
+ *
117
124
  * `true` if the tree node has the focus. Otherwise, `false`. Defaults to `false`.
118
125
  */
119
126
  focus?: boolean;
@@ -130,6 +137,9 @@ export namespace SelectableTreeNode {
130
137
  return is(node) && node.selected;
131
138
  }
132
139
 
140
+ /**
141
+ * @deprecated @since 1.27.0. Use TreeFocusService to track the focused node.
142
+ */
133
143
  export function hasFocus(node: TreeNode | undefined): boolean {
134
144
  return is(node) && node.focus === true;
135
145
  }
@@ -31,7 +31,16 @@ export namespace TreeWidgetSelection {
31
31
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
32
  return Array.isArray(selection) && ('source' in selection) && <any>selection['source'] instanceof TreeWidget;
33
33
  }
34
+
34
35
  export function create(source: TreeWidget): TreeWidgetSelection {
35
- return Object.assign(source.model.selectedNodes, { source });
36
+ const focusedNode = source.model.getFocusedNode();
37
+ const selectedNodes = source.model.selectedNodes;
38
+ const focusedIndex = selectedNodes.indexOf(focusedNode as SelectableTreeNode);
39
+ // Ensure that the focused node is at index 0 - used as default single selection.
40
+ if (focusedNode && focusedIndex > 0) {
41
+ const selection = [focusedNode, ...selectedNodes.slice(0, focusedIndex), ...selectedNodes.slice(focusedIndex + 1)];
42
+ return Object.assign(selection, { source });
43
+ }
44
+ return Object.assign(selectedNodes, { source });
36
45
  }
37
46
  }
@@ -41,6 +41,7 @@ import { TreeWidgetSelection } from './tree-widget-selection';
41
41
  import { MaybePromise } from '../../common/types';
42
42
  import { LabelProvider } from '../label-provider';
43
43
  import { CorePreferences } from '../core-preferences';
44
+ import { TreeFocusService } from './tree-focus-service';
44
45
 
45
46
  const debounce = require('lodash.debounce');
46
47
 
@@ -164,6 +165,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
164
165
  protected readonly treeSearch: TreeSearch;
165
166
  @inject(SearchBoxFactory)
166
167
  protected readonly searchBoxFactory: SearchBoxFactory;
168
+ @inject(TreeFocusService)
169
+ protected readonly focusService: TreeFocusService;
167
170
 
168
171
  protected decorations: Map<string, TreeDecoration.Data[]> = new Map();
169
172
 
@@ -242,7 +245,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
242
245
  this.toDispose.pushAll([
243
246
  this.model,
244
247
  this.model.onChanged(() => this.updateRows()),
245
- this.model.onSelectionChanged(() => this.updateScrollToRow({ resize: false })),
248
+ this.model.onSelectionChanged(() => this.scheduleUpdateScrollToRow({ resize: false })),
249
+ this.focusService.onDidChangeFocus(() => this.scheduleUpdateScrollToRow({ resize: false })),
246
250
  this.model.onDidChangeBusy(() => this.update()),
247
251
  this.model.onNodeRefreshed(() => this.updateDecorations()),
248
252
  this.model.onExpansionChanged(() => this.updateDecorations()),
@@ -268,6 +272,11 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
268
272
  this.updateGlobalSelection();
269
273
  }
270
274
  }),
275
+ this.focusService.onDidChangeFocus(focus => {
276
+ if (focus && this.node.contains(document.activeElement) && this.model.selectedNodes[0] !== focus && this.model.selectedNodes.includes(focus)) {
277
+ this.updateGlobalSelection();
278
+ }
279
+ }),
271
280
  Disposable.create(() => {
272
281
  const selection = this.selectionService.selection;
273
282
  if (TreeWidgetSelection.isSource(selection, this)) {
@@ -342,6 +351,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
342
351
  this.forceUpdate(updateOptions);
343
352
  }
344
353
 
354
+ protected scheduleUpdateScrollToRow = debounce(this.updateScrollToRow);
355
+
345
356
  /**
346
357
  * Get the `scrollToRow`.
347
358
  *
@@ -351,10 +362,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
351
362
  if (!this.shouldScrollToRow) {
352
363
  return undefined;
353
364
  }
354
- const selected = this.model.selectedNodes;
355
- const node: TreeNode | undefined = selected.find(SelectableTreeNode.hasFocus) || selected[0];
356
- const row = node && this.rows.get(node.id);
357
- return row && row.index;
365
+ const { focusedNode } = this.focusService;
366
+ return focusedNode && this.rows.get(focusedNode.id)?.index;
358
367
  }
359
368
 
360
369
  /**
@@ -398,11 +407,6 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
398
407
  this.model.selectNode(node);
399
408
  }
400
409
  }
401
- // It has to be called after nodes are selected.
402
- if (this.props.globalSelection) {
403
- this.updateGlobalSelection();
404
- }
405
- this.forceUpdate();
406
410
  }
407
411
 
408
412
  /**
@@ -411,7 +415,11 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
411
415
  * @returns the node to focus if available.
412
416
  */
413
417
  protected getNodeToFocus(): SelectableTreeNode | undefined {
414
- const root = this.model.root;
418
+ const { focusedNode } = this.focusService;
419
+ if (focusedNode) {
420
+ return focusedNode;
421
+ }
422
+ const { root } = this.model;
415
423
  if (SelectableTreeNode.isVisible(root)) {
416
424
  return root;
417
425
  }
@@ -442,6 +450,9 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
442
450
  if (!this.rows.size) {
443
451
  classNames.push('empty');
444
452
  }
453
+ if (this.model.selectedNodes.length === 0 && !this.focusService.focusedNode) {
454
+ classNames.push('focused');
455
+ }
445
456
  return {
446
457
  className: classNames.join(' '),
447
458
  onContextMenu: event => this.handleContextMenuEvent(this.getContainerTreeNode(), event)
@@ -821,7 +832,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
821
832
  {decorationsToRender.map((decoration, index) => {
822
833
  const { tooltip, data, fontData, color, icon, iconClass } = decoration;
823
834
  const iconToRender = icon ?? iconClass;
824
- const className = [TREE_NODE_SEGMENT_CLASS, TREE_NODE_TAIL_CLASS].join(' ');
835
+ const className = [TREE_NODE_SEGMENT_CLASS, TREE_NODE_TAIL_CLASS, 'flex'].join(' ');
825
836
  const style = fontData ? this.applyFontStyles({}, fontData) : color ? { color } : undefined;
826
837
  const content = data ? data : iconToRender
827
838
  ? <span
@@ -932,7 +943,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
932
943
  style,
933
944
  onClick: event => this.handleClickEvent(node, event),
934
945
  onDoubleClick: event => this.handleDblClickEvent(node, event),
935
- onContextMenu: event => this.handleContextMenuEvent(node, event)
946
+ onContextMenu: event => this.handleContextMenuEvent(node, event),
936
947
  };
937
948
  }
938
949
 
@@ -954,7 +965,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
954
965
  if (this.rowIsSelected(node, props)) {
955
966
  classNames.push(SELECTED_CLASS);
956
967
  }
957
- if (SelectableTreeNode.hasFocus(node)) {
968
+ if (this.focusService.hasFocus(node)) {
958
969
  classNames.push(FOCUS_CLASS);
959
970
  }
960
971
  return classNames;
@@ -1108,6 +1119,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1108
1119
  this.addKeyListener(this.node, up, event => this.handleUp(event));
1109
1120
  this.addKeyListener(this.node, down, event => this.handleDown(event));
1110
1121
  this.addKeyListener(this.node, Key.ENTER, event => this.handleEnter(event));
1122
+ this.addKeyListener(this.node, Key.SPACE, event => this.handleSpace(event));
1123
+ this.addKeyListener(this.node, Key.ESCAPE, event => this.handleEscape(event));
1111
1124
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1112
1125
  this.addEventListener<any>(this.node, 'ps-scroll-y', (e: Event & { target: { scrollTop: number } }) => {
1113
1126
  if (this.view && this.view.list && this.view.list.Grid) {
@@ -1115,7 +1128,6 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1115
1128
  this.view.list.Grid.handleScrollEvent({ scrollTop });
1116
1129
  }
1117
1130
  });
1118
- this.addEventListener(this.node, 'focus', () => this.doFocus());
1119
1131
  }
1120
1132
 
1121
1133
  /**
@@ -1154,6 +1166,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1154
1166
  } else {
1155
1167
  this.model.selectPrevNode();
1156
1168
  }
1169
+ this.node.focus();
1157
1170
  }
1158
1171
 
1159
1172
  /**
@@ -1166,6 +1179,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1166
1179
  } else {
1167
1180
  this.model.selectNextNode();
1168
1181
  }
1182
+ this.node.focus();
1169
1183
  }
1170
1184
 
1171
1185
  /**
@@ -1177,6 +1191,26 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1177
1191
  this.model.openNode();
1178
1192
  }
1179
1193
 
1194
+ /**
1195
+ * Handle the `space key` keyboard event.
1196
+ * - By default should be similar to a single-click action.
1197
+ * @param event the `space key` keyboard event.
1198
+ */
1199
+ protected handleSpace(event: KeyboardEvent): void {
1200
+ const { focusedNode } = this.focusService;
1201
+ if (!this.props.multiSelect || (!event.ctrlKey && !event.metaKey && !event.shiftKey)) {
1202
+ this.tapNode(focusedNode);
1203
+ }
1204
+ }
1205
+
1206
+ protected handleEscape(event: KeyboardEvent): void {
1207
+ if (this.model.selectedNodes.length <= 1) {
1208
+ this.focusService.setFocus(undefined);
1209
+ this.node.focus();
1210
+ }
1211
+ this.model.clearSelection();
1212
+ }
1213
+
1180
1214
  /**
1181
1215
  * Handle the single-click mouse event.
1182
1216
  * @param node the tree node if available.
@@ -1184,29 +1218,30 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1184
1218
  */
1185
1219
  protected handleClickEvent(node: TreeNode | undefined, event: React.MouseEvent<HTMLElement>): void {
1186
1220
  if (node) {
1221
+ event.stopPropagation();
1187
1222
  const shiftMask = this.hasShiftMask(event);
1188
1223
  const ctrlCmdMask = this.hasCtrlCmdMask(event);
1189
- if (!!this.props.multiSelect) {
1190
- if (SelectableTreeNode.is(node)) {
1191
- if (shiftMask) {
1192
- this.model.selectRange(node);
1193
- } else if (ctrlCmdMask) {
1194
- this.model.toggleNode(node);
1195
- } else {
1196
- this.model.selectNode(node);
1197
- }
1224
+ if (this.props.multiSelect && (shiftMask || ctrlCmdMask) && SelectableTreeNode.is(node)) {
1225
+ if (shiftMask) {
1226
+ this.model.selectRange(node);
1227
+ } else if (ctrlCmdMask) {
1228
+ this.model.toggleNode(node);
1198
1229
  }
1199
1230
  } else {
1200
- if (SelectableTreeNode.is(node)) {
1201
- this.model.selectNode(node);
1202
- }
1231
+ this.tapNode(node);
1203
1232
  }
1204
- if (!this.props.expandOnlyOnExpansionToggleClick) {
1205
- if (this.isExpandable(node) && !shiftMask && !ctrlCmdMask) {
1206
- this.model.toggleNodeExpansion(node);
1207
- }
1208
- }
1209
- event.stopPropagation();
1233
+ }
1234
+ }
1235
+
1236
+ /**
1237
+ * The effective handler of an unmodified single-click event.
1238
+ */
1239
+ protected tapNode(node?: TreeNode): void {
1240
+ if (SelectableTreeNode.is(node)) {
1241
+ this.model.selectNode(node);
1242
+ }
1243
+ if (node && !this.props.expandOnlyOnExpansionToggleClick && this.isExpandable(node)) {
1244
+ this.model.toggleNodeExpansion(node);
1210
1245
  }
1211
1246
  }
1212
1247
 
@@ -1233,19 +1268,17 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1233
1268
  const type = !!this.props.multiSelect && this.hasCtrlCmdMask(event) ? TreeSelection.SelectionType.TOGGLE : TreeSelection.SelectionType.DEFAULT;
1234
1269
  this.model.addSelection({ node, type });
1235
1270
  }
1271
+ this.focusService.setFocus(node);
1236
1272
  const contextMenuPath = this.props.contextMenuPath;
1237
1273
  if (contextMenuPath) {
1238
1274
  const { x, y } = event.nativeEvent;
1239
1275
  const args = this.toContextMenuArgs(node);
1240
- this.onRender.push(Disposable.create(() =>
1241
- setTimeout(() => this.contextMenuRenderer.render({
1242
- menuPath: contextMenuPath,
1243
- anchor: { x, y },
1244
- args
1245
- }))
1246
- ));
1276
+ setTimeout(() => this.contextMenuRenderer.render({
1277
+ menuPath: contextMenuPath,
1278
+ anchor: { x, y },
1279
+ args
1280
+ }), 10);
1247
1281
  }
1248
- this.doFocus();
1249
1282
  }
1250
1283
  event.stopPropagation();
1251
1284
  event.preventDefault();
@@ -1360,7 +1393,8 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1360
1393
  state = {
1361
1394
  ...state,
1362
1395
  root: this.deflateForStorage(this.model.root),
1363
- model: this.model.storeState()
1396
+ model: this.model.storeState(),
1397
+ focusedNodeId: this.focusService.focusedNode?.id
1364
1398
  };
1365
1399
  }
1366
1400
 
@@ -1373,7 +1407,7 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1373
1407
  */
1374
1408
  restoreState(oldState: object): void {
1375
1409
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1376
- const { root, decorations, model } = (oldState as any);
1410
+ const { root, decorations, model, focusedNodeId } = (oldState as any);
1377
1411
  if (root) {
1378
1412
  this.model.root = this.inflateFromStorage(root);
1379
1413
  }
@@ -1383,6 +1417,12 @@ export class TreeWidget extends ReactWidget implements StatefulWidget {
1383
1417
  if (model) {
1384
1418
  this.model.restoreState(model);
1385
1419
  }
1420
+ if (focusedNodeId) {
1421
+ const candidate = this.model.getNode(focusedNodeId);
1422
+ if (SelectableTreeNode.is(candidate)) {
1423
+ this.focusService.setFocus(candidate);
1424
+ }
1425
+ }
1386
1426
  }
1387
1427
 
1388
1428
  protected toNodeIcon(node: TreeNode): string {