947338cb1a4b85d386a9a3d76335fb35e1b91f34ff97a3f64d6c1b8343c8935cbc9080b698dbaabe5983542e0fb1a5d38c9ebbf87b93600b5ae9a98bdc211e 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { range } from '../../../common/arrays.js';
  6. import { CancellationTokenSource } from '../../../common/cancellation.js';
  7. import { Event } from '../../../common/event.js';
  8. import { Disposable } from '../../../common/lifecycle.js';
  9. import './list.css';
  10. import { List } from './listWidget.js';
  11. class PagedRenderer {
  12. constructor(renderer, modelProvider) {
  13. this.renderer = renderer;
  14. this.modelProvider = modelProvider;
  15. }
  16. get templateId() { return this.renderer.templateId; }
  17. renderTemplate(container) {
  18. const data = this.renderer.renderTemplate(container);
  19. return { data, disposable: Disposable.None };
  20. }
  21. renderElement(index, _, data, height) {
  22. if (data.disposable) {
  23. data.disposable.dispose();
  24. }
  25. if (!data.data) {
  26. return;
  27. }
  28. const model = this.modelProvider();
  29. if (model.isResolved(index)) {
  30. return this.renderer.renderElement(model.get(index), index, data.data, height);
  31. }
  32. const cts = new CancellationTokenSource();
  33. const promise = model.resolve(index, cts.token);
  34. data.disposable = { dispose: () => cts.cancel() };
  35. this.renderer.renderPlaceholder(index, data.data);
  36. promise.then(entry => this.renderer.renderElement(entry, index, data.data, height));
  37. }
  38. disposeTemplate(data) {
  39. if (data.disposable) {
  40. data.disposable.dispose();
  41. data.disposable = undefined;
  42. }
  43. if (data.data) {
  44. this.renderer.disposeTemplate(data.data);
  45. data.data = undefined;
  46. }
  47. }
  48. }
  49. class PagedAccessibilityProvider {
  50. constructor(modelProvider, accessibilityProvider) {
  51. this.modelProvider = modelProvider;
  52. this.accessibilityProvider = accessibilityProvider;
  53. }
  54. getWidgetAriaLabel() {
  55. return this.accessibilityProvider.getWidgetAriaLabel();
  56. }
  57. getAriaLabel(index) {
  58. const model = this.modelProvider();
  59. if (!model.isResolved(index)) {
  60. return null;
  61. }
  62. return this.accessibilityProvider.getAriaLabel(model.get(index));
  63. }
  64. }
  65. function fromPagedListOptions(modelProvider, options) {
  66. return Object.assign(Object.assign({}, options), { accessibilityProvider: options.accessibilityProvider && new PagedAccessibilityProvider(modelProvider, options.accessibilityProvider) });
  67. }
  68. export class PagedList {
  69. constructor(user, container, virtualDelegate, renderers, options = {}) {
  70. const modelProvider = () => this.model;
  71. const pagedRenderers = renderers.map(r => new PagedRenderer(r, modelProvider));
  72. this.list = new List(user, container, virtualDelegate, pagedRenderers, fromPagedListOptions(modelProvider, options));
  73. }
  74. updateOptions(options) {
  75. this.list.updateOptions(options);
  76. }
  77. getHTMLElement() {
  78. return this.list.getHTMLElement();
  79. }
  80. get onDidFocus() {
  81. return this.list.onDidFocus;
  82. }
  83. get onDidDispose() {
  84. return this.list.onDidDispose;
  85. }
  86. get onMouseDblClick() {
  87. return Event.map(this.list.onMouseDblClick, ({ element, index, browserEvent }) => ({ element: element === undefined ? undefined : this._model.get(element), index, browserEvent }));
  88. }
  89. get onPointer() {
  90. return Event.map(this.list.onPointer, ({ element, index, browserEvent }) => ({ element: element === undefined ? undefined : this._model.get(element), index, browserEvent }));
  91. }
  92. get onDidChangeSelection() {
  93. return Event.map(this.list.onDidChangeSelection, ({ elements, indexes, browserEvent }) => ({ elements: elements.map(e => this._model.get(e)), indexes, browserEvent }));
  94. }
  95. get model() {
  96. return this._model;
  97. }
  98. set model(model) {
  99. this._model = model;
  100. this.list.splice(0, this.list.length, range(model.length));
  101. }
  102. getFocus() {
  103. return this.list.getFocus();
  104. }
  105. getSelection() {
  106. return this.list.getSelection();
  107. }
  108. getSelectedElements() {
  109. return this.getSelection().map(i => this.model.get(i));
  110. }
  111. style(styles) {
  112. this.list.style(styles);
  113. }
  114. dispose() {
  115. this.list.dispose();
  116. }
  117. }